While the Servlet 3.0 spec has request.startAsync() and asyncContext.start(),
why has it not provided a asyncContext.stop() or asyncContext.cancel() to initiate necessary clean-up on the server-side ?
Pls view this in the context of this other question to understand where I am coming from.
One HTTP request starts the Async processing and returns a
.../outstandingRequests/requestId link to the client.
Another HTTP request calls DELETE on that link to cancel the request
In this case, if I had a way to clean-up the server-side (servlet container stuff like AsyncListeners), instead of having to call asyncContext.complete() which will probably try and send a response back to the client, it will make sense. Doesnt it ?
In this scenario, call 1 is still hanging there, waiting for its response when call 2 comes in and wants to kill it. In this scenario, why would you not want to call complete() on call 1, thus finishing that call so that client stops waiting? You would probably want to set the status code to something other than 200 in this type of situation, but complete seems too be the best option given any scenario because it returns control back to the original caller and performs any request related cleanup work.
When a timeout happens, which is an error, the container calls complete (with a non-200 response code I imagine). The scenario you describe is similar to a timeout (albeit a forced timeout), so why not do the same thing the container does. Just call something like this before calling complete:
ac.getResponse().setStatus(500);
Any maybe write something to the output stream describing what caused this error.
Related
In Java in a web service, I have a requirement I want to return the response to the user after configured threshold time reaches and wants to continue processing after that.
Let's say I have a service it does step1, step 2, and the configured threshold is 1 second. Let's say step1 is completed at 1 second I want to return an acknowledgment response to the user and continue processing with step2 and wants to store response in DB or something like that.
Please let me know if anyone has any solutions or thoughts on this problem
There are multiple ways to achieve this
HTTP Layer
On HTTP layer, if the response comes back before the threshold, then I'd be tempted to send back a 200 Success.
However, if it takes more time than the threshold, you could use 202 Accepted
Looking at the RFC, its use case looks like this
6.3.3. 202 Accepted
The 202 (Accepted) status code indicates that the request has been
accepted for processing, but the processing has not been completed.
The request might or might not eventually be acted upon, as it might
be disallowed when processing actually takes place. There is no
facility in HTTP for re-sending a status code from an asynchronous
operation.
The 202 response is intentionally noncommittal. Its purpose is to
allow a server to accept a request for some other process (perhaps a
batch-oriented process that is only run once per day) without
requiring that the user agent's connection to the server persist
until the process is completed. The representation sent with this
response ought to describe the request's current status and point to
(or embed) a status monitor that can provide the user with an
estimate of when the request will be fulfilled.
Now, of course, instead of having a mix of 200 and 202, you could just return 202 everytime
Application Layer
In your application layer, you'll typically want to make use of asynchronous processing for this purpose.
There are multiple ways to leverage this way of working, you can:
Post a message on a queue/topic and let a message broker take care of dispatching it to another part of the app, or another app and let this part do the processing
Save the request inside of a database, and have another service poll the database for new requests, similar to queueing explained above, without JMS
If you're using Java EE, your EJB container allows you to work with #Asynchronous which will call a method asynchronously and return (so you'll be able to return 202)
If you're using Spring, it has an #Async annotation for the same purpose as hereabove
There are definitely other methods you could use to achieve this use case, but I think the ones I presented are the most common ones
Hy, I have made a java application using asterisk-java and from it I can receive a call and can initiate outbound as well. But I am facing one problem that whenever I bulk outbound calls to say 50k users, the application can handle only those who answered the calls not those who unanswered or didn't responded. Also as I have set the value of
OriginateAction.setAsync(true)
in my outbound calling application so I am getting success response to every call, which means call is successfully initiated, but if this value is not set then although I can check the response (error: incase the user didn't responded the call), but then in this case outbound bulk drops from 50k to 3k.
My Ideal solution would be if the call is not answered and is hung up eventually then I can redirect it to some AGI script, which would show its record (hangup cause, Answered/Busy/etc)
Kindly guide.
You have manage number of call yourself.
Asterisk not designed to know how many calls at once your hardware/trunks can support,that interface just for place SINGLE call.
Check vicidial dialler or other project writed before.
I have a Spring Web flow application running on Weblogic 10. In current application, on load of the Page A , we are making an ajax call , which in the back end makes a webservice call WEBSVCA. On the submission of the same page,we have another webservice call being made WEBSVCB. The application requires that WEBSVCA call should always be made and completed before WEBSVCB call starts. But sometimes, when the user submits the page very fast, WEBSVCA response has not comeback yet and the call to WEBSVCB fails because of the concurrent call.
In order to resolve the above problem, I was planning to implement BlockingQueue for the webservice call status. In this case, the response from the WEBSVCA can be used as Producer and before the call to WEBSVCB is made we can check the queue as consumer.
Is is this the best approach or there could be a simpler approach than this??
Please let me know if you need any other details.
If the user can't progress to the next page before WEBSVCA has finished, then it shouldn't be an ajax call - so you could just do it as part of the page load.
Or, disable the submit button by default, then only enable it when the ajax callback succeeds.
For my game, I have it running on two servers (one for the game, one for the login system). They both need to interact with each other, and sometimes, ask questions about the state of something else in the other server.
For this example, the game server will be asking the login server if a player is trying to log in:
public boolean isLoggingIn(int accountId) {
//Form a packet to send.
int retVal = sendData();
return retVal > 0;
}
Obviously I'd use an int so information other than booleans can be returned.
My question is, how do I get this modal-style programming working? It'd work just like JFileChooser's getOpenDialog() function.
Also, I should mention that more than one thread can call this method at once.
I assume by modal, you mean trying to block all actions except one. I strongly suspect that this style will lead you into trouble. Modal interaction is a form of locking and therefore not very tolerant to hangups and disconnects and such. To make it tolerant, you need timeouts and cleanup code for cases when someone entered a mode and then nothing further happened. (i.e they closed their laptop, or the game crashed, they unplugged the network cable etc).
If I were you I would instead try to think of things in terms of authentication and authorization.
The quick answer - you need to expose methods on both servers as RMI-capable, and simply invoke methods like you described.
You might find it useful to review the official Oracle RMI tutorial: http://docs.oracle.com/javase/tutorial/rmi/index.html
Althought your design might be wrong - it's your design, and why not letting you shoot your head? ;)
Also, it's worth looking at Spring Security: http://static.springsource.org/spring-security/site/
If you use something like this on a thread that is supposed to handle other requests after it, it would hang up all those requests while it is blocking for a return value if the latency between the game and login servers is high. Certainly what you want instead is a callback so that your thread could handle other requests while it waits for a response.
I see no reason to halt execution of a thread until a value is received. If you need the value for an operation after it, then just copy all the code you have after the call you want to be "modal" in the callback. If you expect to send multiple requests while still waiting for a response, then send a unique "responseId" from the requester's side that the responder can include in its response. Use the "responseId" as a key for a Map with Runnables as values. When you receive a response, call remove on the Map with the responseId key and call run() on the Runnable value that is returned. MINA is supposed to asynchronous and should not block for a response packet.
If you have a really good reason for why you want to handle it all on the same thread, you can look into the java.util.concurrent package. I would implement it using a CountDownLatch of count 1, call await() after sending a request message, and call countDown() when you receive a response by MINA. You have to use an AtomicReference or an array of length 1 to hold the value you received in the response that you can read back into the waiting thread.
PS, you still doing MapleStory work?
I'm facing this problem: after clicking on a button, I make a request to the server and get some data; then, I display the data on a new page/view. This raises a problem: the UI has to wait while the request is being made and data is being received, parsed and set on the view. This results in the user having to wait until all the data is loaded before even being able to go back, and doesn't even have the chance to cancel the call. Multithreading would solve the issue, and that's where I need help.
The HTML5 Web Workers would do the trick for me, however I don't want to "hard code" them in JSNI and have all the calls written with Javascript instead of GWT Java (RequestBuilder). I've read about DeferredCommand but I also don't think it's the answer to my issue.
Any suggestions? Or this is an impossible optimization, at the moment?
In JS, therefore GWT, there is no multithreading. Instead you should use asynchronous calls with callbacks. Normally when you use GWT RPC for communication, you issue a request and handle result in onSuccess event. Alternatively you can always use Timer to check for result periodically. I'm not sure what kind of request you are making, so hard to be specific. Probably you should check appropriate section of Communicating with the server
EDIT: I've just noticed you mention RequestBuilder. The sendRequest() should not block execution and you should process result in RequestCallback.onResponseReceived() of provided callback. Which mean you somehow continue your button event handling in that callback.