Can I check if an async request completed? - java

Is there any way to check if an async ServletRequest is completed from an AsyncContext? I saw that spring has some kind of wrapper that supports this but googling around I couldn't find anything in the standard library. That is what I was hoping for.
I am using Tomcat 7.

Sounds like one of the two - you either need a listener that will be called upon a asynchronous request completion or you don't need to use an asynchronous call.
Your question is a bit too general.
Talking generally - asynchronous calls are used when the caller is not interested in immediate result of the call.
If the caller is interested to know the result of the call immediately then synchronous calls should be used.
If the caller is not interested to know the result immediately (for example it has secondary priority, like logging in some business applications), but some action should be performed upon the end of execution of asynchronous calls you should use some sort of a listener.
What you need for asynchronous call is some listener (of class javax.servlet.AsyncListener).
In the listener you will know for sure that the asynchronous call is over (onComplete method) and may perform some action to finalize/complement the asynchronous call.
Again, if you see that the caller of the request needs to know the result upon completion immediately, there probably is a mistake in your architecture. You should use a synchronous call - just wait until the call is done and you will have the result of it. Using an asynchronous call is wrong in this situation.
I saw how people use some sort of a loop to check from time to time the result of a asynchronous call, but it looks like in 99.99% of cases such approach is the result of some architectural mistake.

You can register AsyncListener which can implement onComplete() method.
The AsyncListener needs to be added to the AsyncContext.

Related

HTTP Request from EJB Bean

EJB Spec says you shouldn't manage threads. I have seen Bean code that sends remote requests and loops with a Thread.sleep waiting for a response to reduce CPU usage. From what I understand this breaks spec. Does simply calling the logic from a separate POJO or library that is instantiated then referenced in the EJB's method fix this? Does simply removing Thread.sleep fix the issue at the cost of additional CPU consumption? How should external synchronous requests be coded in EJBs?
That depends on the business case. EJB spec provides plenty of resources for async/sync processing without boilerplate code using Thread, Runnable or any other mechanism.
To execute a piece or code asynchronously (that is, the caller won't wait for the response, but carry on), use #Asynchronous, and Future<T> if you want to listen for responses afterwords.
A synchronous call, as you called, is a call that waits for the response, so "How should external synchronous requests be coded in EJBs" is something that doesn't need any kind of asynchronous/background execution. You just make the call and the code itself wait for the response (otherwise it would be asynchronous), being the tipical case a Web Service (either REST or SOAP).
Web Services calls can actually be synchronous or asynchronous, that depends on the business case, but they are usualy synchronous, you make the call and receive a response with the data. In cases of business logic that takes a while to execute, the Web Service receives the resquest and may launch the business logic asynchronously (with an #Asynchronous for instance) and respond immediately with a plain HTTP 202 - Accepted, which basically means "Hey! The request you just sent me is gonna take a while, so I'll do it in the backround".
In that case, may be you have another web service that you need to check to see how that long lasting process is going. That is the only case I can think of in which someone will want that Thread.sleep(...) in a loop, checking the Web Service until it tells you that the process have finished.
Luckily, EJB also provides a solution for that business case:
You can use #Schedule methods in case you need to check/do something indefenately, in specific intervals: something to do every day at 02:00, or every first day of month, or even every 2 seconds.
Or TimerService and #Timeout, in case you want to programatically schedule a single task. This last fits better in the business case we are talking.
So you call the TimerService with the timespan you want to wait for the next check. When time comes the #Timeout method is fired, in which you can check whatever you need, and shcedule another execution in case you need it, even with a new timespan.

Java: Best way to delegate to method w/o waiting for it to complete

I have a AWS SQS listener that, when it receives a message, invokes the proper method to handle it. The problem is that it also waits for that method to return, and if it takes longer than the visibility timeout, we get the message again. Take this for instance:
if (FULL_LOAD.equalsIgnoreCase(msg.getLoadType())) {
//Create the controller and process the message
log.info("Process valid Full Load message from "+msg.getDataSourceName());
productRefService.fullRefresh(ctx);
jobCompletion(msg, jobStart, start);
}
// continue processing
So right now, before the listener can continue, it must wait for productRefService.fullRefresh to complete, which can be up to 15 minutes. It seems to me there should be a way to invoke the service method and continue, but I'm not sure how that would look. Make productRefService async?? Use the Callable interface? I'm not interested in the return value - I just want the listener freed up.
Per your request:
Good question! If you're on Java 8 or higher, consider
CompletableFuture:
Asynchronous Programming in Java
Guide To
CompletableFuture
A Java "CompletableFuture" is analogous to Javascript "Promises" or C#
"async/await". It's return value gives the caller something to "wait
on" (if it needs to).

Is it in anyway possible to stop a REST call?

From Javascript, I am calling a REST method which is computationally intensive. Would it be possible to stop that REST call, if you are no longer interested in what it returns.
I understand, it is possible to abort a request in JS. But it won't stop the thread which gets triggered due to the REST call. This is how I am aborting the ajax call in JS.
Abort Ajax requests using jQuery
The REST interface is written in Java. And internally this thread may create multiple threads also.
I would like to stop a Java thread. But from the caller. From JS, where I have triggered it.
How to properly stop the Thread in Java?
As Chris mentioned in the comments above, REST calls should be quick, definitely not an hour long. If the server needs to do a lot of work which takes considerably amount of time, you should modify your design to async. Either provide a callback that the server will use once it's done (also called push approach), or pull every few minutes, by sending a new request to the server to see if it's done.
In order to implement it you'll need the server to return a unique-id for each request in order to be able to identify in the callback/check-call what's the status of that specific request.
The unique-id should be implemented on the server-side in order to avoid two clients send the same ID - overriding each other.
In the link that I posted above you can see an example of how to implement a "stop thread" mechanism which can be implemented on the server-side and called by the client whenever is needed.
You could send a unique identifier along with your request, and then make another request that instructs the server to abort the operation started for that ID.

In Java is a callback synchronous?

When you use a callback in Java (you can't do that right?), does it block execution until everything is finished? Am I using the wrong terminology. I am familiar on the purpose of a Callback as it relates to Inverion Of Control, Interface, etc., just not the sequence of events.
Converting to an answer from a comment:
All method calls are synchronous, in that they return a result to the caller. However, a callback implies potential asynchronous behavior wherein you define a method to execute when some action is complete. For that matter, the state of the application may determine whether the call is synchronous (i.e. caching of resources). In order to know whether the underlying action is synchronous or asynchronous you need to read the documentation for whatever library you are using. In summary: read the docs
A callback is just a piece of code to execute. It can be invoked synchronously or asynchronously.
Yes.
That's not to say that invoking the callback won't start a new thread internally to do something asynchronously, but the callback method itself is synchronous.

Wrapping a callback function in a single threaded fashion

In my program, I am essentially trying to connect to a publisher and get data. The basic functionality is there in these steps
I make the connection to the publisher with username and password etc
I make the request for data. Method exits
The publisher's API gives me a callback to a method onDataUpdate(Object theUpdate)
From there, I can print the data, or write it to a database or anything I need to do. That all works.
My problem is, I would now like to wrap the functionality in such a way that a calling program can say request the data and receive it as soon as I have it. Meaning, I want my exposed method to look like
public Object getData() {
subscribeForData();
// somehow wait
return theUpdate;
}
How can I make this happen? Is there some way I can use threads to wait/notify when I've received the update? I'm a newb to stackoverflow and also multithreaded programming, so any help and sample code would be much appreciated!! Thanks in advance.
In this case I would prefer to use CountDownLatch, where i'll initialize my lathch with count 1 as soon i subscribe for publisher i will call await() on latch and when i get the callback i'll countdown the latch.
Use a SynchronousQueue. Create it in getData, call put() in the callback method, then call take() in the original thread at the end of getData().
Check out CompletionService, especially ExecutorCompletionService. There is a nice example of a web page loader/renderer in the book Java Concurrency in Practice.
I'm not entirely certain about your question but I'll give it a shot - hope it helps :)
You could use a blockingqueue in java for this purpose (producer consumer message) - if you write to the queue when the callback gets invoked - from another thread, you could read from the queue. Blocking queues are thread safe (but may not fit your requirements).
You could also look into readwrite locks if you only have one thread writing to a collection and perhaps multiple readers (or even just on reader).
You could also look into the observer pattern - for reference: http://www.vogella.com/articles/DesignPatternObserver/article.html
If neither of those work, one could look into using a queue/topic from an in-VM messaging server such as ZeroMQ/ActiveMQ or perhaps something like Redis/HazelCast.
Hope it helps and good luck
Converting a asynchronous call to a synchronous one is an interesting exercise, I use it often in interviews (and the reverse, wrapping a synchronous call in asynchronous).
So there is a requestData method that is going to return immediately and it (or something else) will later call onDataUpdate in a different thread. You want to create a new method, say requestDataSynchronous that does not require the caller to use a callback but instead blocks till data is available and returns it to the caller.
So what you need for requestDataSynchronous to do is:
call requestData
wait till onDataUpdate is called (in a different thread)
get the data onDataUpdate received
return it to the caller
Of the above, #2 and #3 have to be done by some mode of inter-thread-communication. You can use wait/notifiy but it might be much simpler to use a BlockingQueue. onDataUpdate writes to it once data is available, and requestDataSynchronous reads from it, blocking on the read until onDataUpdate writes into it.
Using ExecutorService might make this even easier, but it will be useful to know what's going on.

Categories