I am developing a spring 4 mvc application and I've got a database transaction that has to be done in the background.
It is triggered, when the URL /paramters_selected is called. The controller then starts an asynchronous task that is going to take a few minutes. For the time of processing the task, I return "processing" so that the controller method will render the /processing - JSP view. When the background task is finished, the "result" view should be rendered.
Is it possible, and if so how would it be done, to call /result when the background transaction has finished? Furthermore, is it possible to constantly update the "processing" view so that some kind of progress bar could be used?
Additonally, what kind of "technique" is best suited for this problem? I came across the terms of async-methods in spring, completable futures, deferredresult and listenablefuture.
Thank you in advance.
If you are using Async then i would suggest you not to wait for the result from server and better keep on either refreshing the status after some time or create callback which keeps on listening to response from server for Async Tasks.
If you use progress bar till Async task is completed, i suppose you mean just to show in UI and HTTP connection for that request is completed once the request is sent to Async task otherwise holding resource is not good as it will impact performance of the system and other tasks waiting for resource will eventually die due to unavailability of free resources.
So for Async task you can use any of the Java messaging queue, wherein your task will be pushing into JMS queue and Async task will keep of deque from JMS queue and once task is completed send response in form of notificaiton to originating task.
By using WebSocket you can implement this feature in a real time way.
http://docs.spring.io/spring/docs/current/spring-framework-reference/html/websocket.html
Related
We are using Akka actors in our application. Actors are invoking services and in some cases those services are calling rest API exposed by third party. Now the third party APIs are taking a very long time to respond. Due to this during peak time , the system through put is getting impacted as threads are blocked as they wait for client API to respond.
Sometimes during peak time , because threads are waiting , messages just keep waiting in akka mail box for long time and are picked up, once blocked threads are made available.
I am looking for some solution where in i can improve the throughput of the system and can free up threads so that actor messages can start processing.
I am thinking to change the rest API call from blocking to non blocking call using Future and creating a dedicated actor for such kind of rest API invocations . Actor will periodically check if future is completed and then sends a completion message and then rest of process can continue.This way the number of blocking threads will reduce and they will be available for actor message processing.
Also would like to have separate execution context for actors which are doing blocking operations. As of now we have global execution context.
Need further inputs on this.
Firstly, you are correct that you should not block when processing a message, so you need to start an asynchronous process and return immediately from the message handler. The Actor can then send another message when the process completes.
You don't say what technology you are using for the REST API calls but libraries like Akka HTTP will return a Future when making an HTTP request so you shouldn't need to add your own Future around it. E.g:
def getStatus(): Future[Status] =
Http().singleRequest(HttpRequest(uri = "http://mysite/status")).flatMap {
res =>
Unmarshal(res).to[Status]
}
If for some reason you are using a synchronous library, wrap the call in Future(blocking{ ??? }) to notify the execution context that it needs to create a new thread. You don't need a separate execution context unless you need to control the scheduling of threads for this operation.
You also don't need to poll the Future, simply add an onComplete handler that sends an internal message back to your actor which then processes the result of the API call.
Currently, I am working on a rest API through which client can submit a forever running task and it should return started confirmation if there is no error. The client should be able to submit any number of similar tasks. There should be a functionality to check the status and cancel any task. Currently, I am trying to do it in Java using Spring. How should I approach the problem?
I was able to create an asynchronous task in Spring each time I sent a post request. But till now unable to figure out how to check the status and cancel any task.
Threads you can use here.
Create a job executor class responsible for running the task.
Make a callable. So, you would be able to get the result in the Future.
Use BlockingQueue for the task to store and pick from it (you should because of processor i.e. dual/4 cores).
Use Runtime Class to get the Cores available and Run the thread in cores-1.
No. of thread = Available cores-1.
for cancellation, you can use a flag that mapped to respected stored Thread. Check that flag and return if thread started at any point of time
Context:
1) We have a scheduler which picks up jobs and process them by calling another rest-call in a blocking manner.
2) Scheduler thread needs to wait for the rest-call to complete and in-turn do some another task based upon the result.
3) There is no constraint for this to be real time.
Problem Statement:
1) What we want is to free scheduler threads as soon as an external call is made as external call takes significant time to complete.
2) We should be informed about the result received from the external call as we need to do some processing based on the result.
Idea in my mind:
1) Rather than calling the external system using synchronous Http call, we
can push the event to the queue.
2) Api consumer of another system will read the event from the queue and do the long running task. And post processing push the result back to the queue on a different topic.
3) Our system now can read the response from the queue(second topic) and do the necessary actions.
This is one of the design approach that comes to my
I need advice on whether we can improve the design somehow.
1) Can this be done without introduction of queue ?
2) Is there any better way to achieve the asynchronous processing ?
If you want to avoid using a queue, I can think of 2 other alternatives, for example:
1) Rather than calling the external system using synchronous Http call, we can push the event to the queue.
alternative a)
you do a synchronous HTTP GET to tell the other system that you want certain job to be executed (the other system replies quickly with a "200 OK" to confirm that it received the request).
alternative b)
you do a synchronous HTTP GET to tell the other system that you want certain job to be executed (the other system replies quickly with a "200 OK" and a unique ID to identify the job to be executed)
2) Api consumer of another system will read the event from the queue and do the long running task. And post processing push the result back to the queue on a different topic.
3) Our system now can read the response from the queue(second topic) and do the necessary actions.
alternative a)
upon receiving the request, the other system performs the long running computation and then when it is ready it makes a synchronous HTTP call to your original system to inform that the job is ready.
alternative b)
upon receiving the request, the other system performs the long running computation.
the original system doesn't know if the job is done, so it polls at certain times (doing a synchronous HTTP GET to a different REST API) providing the JOB ID, to find out if the job is ready.
I am creating Executor in a web project so that the callable can do the work after the response has gone back to the web. Work that callable is doing behind the scene is not required for the current page but for one the pages that will follow.
As far as I know when then the response goes back to the web the servlet thread is free to process another request. In this case although the servlet thread created a executor service it should be available to process another incoming request as soon as the response is sent back even if the callables are active. Is my understanding correct?
If you are creating a new thread, which it sounds like you are, then you are correct. The thread handing the Servlet request goes back in the pool and is free to return results and take the next request.
I need to wait for a condition in a Spring MVC request handler while I call a third party service to update some entities for a user.
The wait averages about 2 seconds.
I'm calling Thread.sleep to allow the remote call to complete and for the entities to be updated in the database:
Thread.currentThread().sleep(2000);
After this, I retrieve the updated models from the database and display the view.
However, what will be the effect on parallel requests that arrive for processing at this controller/request handler?
Will parallel requests also experience a wait?
Or will they be spawned off into separate threads and so not be affected by the delay experienced by the current request?
What are doing may work sometimes, but it is not a reliable solution.
The Java Future interface, along with a configured ExecutorService allows you to begin some operation and have one or more threads wait until the result is ready (or optionally until a certain amount of time has passed).
You can find documentation for it here:
http://download.oracle.com/javase/6/docs/api/java/util/concurrent/Future.html