Java Web Application : Monitoring Progress - java

Many times there are some long running processes called by http servlets in java web application. A typical example will be, converting 100 mp3 files to flak format (just a random example). The http connection will be alive but since the process will take long long time, we can build some progress bar to display on the web page (preferably uisng ajax) which indicates the progress of the task. What should be the design pattern for this? Say, Servlet's post method will invoke the actual long term process, and Servlet's get method will invoke the progress listener?

In Java EE I would recommend the following structure:
a Servlet call (POST for example) will start the process
the POST will use an #Asynchronous EJB call to process the heavy load, so that will start doing the long-taking process
It will also pass a progress holder object, e.g. a POJO which is put into the context/session (a #Stateful EJB will also do)
the POST returns, the background job continues
The status check is carried out by Ajax HTTP calls, they use the same session as the starter
the Ajax call gets the progress holder object from session/context/#Stateful, reads the status and returns
the status is continuously updated by the background thread (the update should be synchronized unless you use only one attribute of boolean, char, int or float (max 32bit primitives))
Note that #Asynchronous is available since EJB 3.1.

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.

Tomcat Thread Model - Does a thread in Thread per request model handle all work related to that request?

I understand that the Servlet Containers will use "Thread per request" model, but my question is, will the thread handling the request do all the below steps ?
Obtain thread from pool to handle request and and pass http request and http response objects to Servlet service method.
Invoke service/dao/ logic which could potentially involve delay since I/O operation is done in DB.
Return the Http response
Return the thread to the Container Thread pool
My main questions is, if somehow the I/O operation on step 2 takes a huge amount of time, will the Servlet container run out of threads from the pool ? Or does the Container use one thread/threads just to handle the request and then delegates the work to another thread to do the rest of the work ? Also I heard that nowadays they are changing the model to a Threaded Model with NIO operations? Thank you.
will the same thread be used for everything ?
TL;DR - No.
Once the Servlet Container (Catalina) spins up the thread per request, that thread is deallocated/exited right after that request-response cycle is finished (that is, corresponding HTTP request handler Servlet method returns).
If your service (DAO/logic/whatever) layer will block the thread, which eventually blocks the web layer (doGet(), doPost() or etc.), browser will go idle, awaiting the response (time is either default or configured), and Catalina (Servlet Container) will block that thread only (other requests may arrive successfully);
I/O (or to be specific Request-Response) timeout will be either default (which is 60 seconds, but it depends on the Tomcat version), or configured by yourself;
Design of the architecture, to delegate discrete incoming HTTP Message to separate threads, has a sole and simple purpose - to process the Request-Response cycles in isolation.
Head First Servlets & JSP:
The Container automatically creates a new Java thread for every servlet request it receives. When the servlet’s done running the HTTP service method for that client’s request, the thread completes (i.e. dies).
Update to your updated question
my question is, will the thread handling the request do all the below steps?
TL;DR - No again.
Servlet Objects live in container, which is a completely separate thread.
When the HTTP message (request, in this case) hits the Servlet-mapped endpoint, this happens:
Servlet Container creates HttpServletResponse and HttpServletRequest objects;
Container allocates(creates) a new thread for that request and response objects (Important: in order to isolate client-server communication.);
Container then passes those request and response objects to the servlet thread;
Container then calls the Servlet API's service() method and depending on what is the type of incoming message (GET, POST, etc.), it invokes corresponding method (doGet(); doPost(); etc.);
Container DOES NOT CARE whatever levels or layers of architecture you have - DAO, Repository, Service, Cherry, Apple or whatever. It will wait until the corresponding HTTP request handler method finishes (accordingly, if something blocks it, container will block that thread);
When the handler method returns; thread is deallocated.
Answering your further questions
My main questions is, if somehow the I/O operation on step 2 takes a huge amount of time, will the Servlet container run out of threads from the pool ?
Theoretically it can; however, that means, that it should block all the 200 threads at the same time and this time (if the default configuration is maintained) it will not accept any other requests (until some thread deallocates).
This, however, can be configured with maxThreads attribute and you can choose what should be the threshold number of request processing threads allowed in Tomcat.
Or does the Container use one thread/threads just to handle the request and then delegates the work to another thread to do the rest of the work?
We have answered this above.
Also I heard that nowadays they are changing the model to a Threaded Model with NIO operations?
NIO specific configuration and it can facilitate poller threads, which are used to simultaneously handle multiple connections per thread; however, this is a big and completely different topic. For the further reading, have a look a this and this.
PLEASE, make sure that your future posts are not too broad, containing 10 different questions in a single post.

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.

Display immediate searched result from long process in Struts2 before finish

I'm doing a program in Struts2 that is parsing some xml from some list of urls and store the list of beans in HttpSession. This is a long running process, because it has to download xml from url, parse it, and create bean. I want to design this task such a manner so that when it will get request from client, it will start parsing and store the result in session. When it finishes parsing some xml it notify the page or Struts from java so that it able to show some results before all parsing the rest of url being completed. I'm already using this parsing in different thread. But it has risk, because web manages different thread pool for each different client request and it has the possibility of memory leak. I already have a look in execAndWait
, but it is not possible to display some result bean during parsing process.
Any one can tell better way or better solution.
I solved my problem. First of all create an interceptor project and extends ExecuteAndWaitInterceptor.java instead of Interceptor interface and override doIntercept method. Just we have to use getNewBackgroundProcess() in doIntercept method. This method mainly create a background thread. If you control this interceptor, then we don't need to wait for uncertain delay. If we control this mechanism then we can call intermediate page when one bean is ready to display before long process being finished. All control will be in my hand, when it should be called. And we don't need to use delay and interval delay, because any bean might not be ready to display after this delay.

Keeping a reference to a background thread in Grails?

My Grails 1.3.7 app needs to process big XML files, so I have a controller to which I upload the big file, and then I give the path of this file on the server to a background thread that does the processing so that I can return right away from the controller action.
For now, I am using the Grails Executor plugin and it works fine. I have an Upload domain object that is updated as the processing progresses (current status, number of processed elements, etc.). But now I have 2 more requirements:
when the application crashes or the server is shutdown, I would like to intercept that and update my Upload domain to say that the process was interrupted
I want the user to be able to interrupt the processing himself when clicking a link and possibly resume it from controller actions
Is there a way that I can persist a reference to my background task and intercept any interruption with java.util.concurrent framework (which is used by Executor plugin)?
And if I can't do it with util.concurrent, is it possible with other plugins/frameworks? I've had a look at Quartz for example, but I don't see how to do it.
I hate to answer without fully testing it, but the grails-executor plugin docs state that the callAsync method returns a java.util.concurrent.Future object.
This object can be used to do two things:
Determine if a process has completed or been canceled.
Cancel a running process (even interrupting if necessary).
In theory, you should be able to save this Future in your user's session somewhere. Then you could retrieve it later and use it to check the status and/or cancel the process as necessary.
Something like:
session.backgroundProcess = callAsync{...}
// later
def bgProc = session.backgroundProcess
if(bgProc && !(bgProc.done || bgProc.cancelled)) {
// process is still running
}
That's just the idea, it's not tested. I also don't know if there are issues with this leading to memory leaks. You'd need to make sure you detached the Future once the process is completed.

Categories