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.
Related
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.
The scenario of my problem is:
In my servlet I get a large amount of data from somewhere (not relevant). I have to iterate over all this data and put it in an array, convert it to a JSON object and send it to the client side for viewing. If I do this in a single response it takes a very long time to display the results. Hence, I need to do multithreading.
The created thread needs to keep on adding data to the list while the main thread whenever it gets a request (requests for data keep on coming periodically) sends the present available list.
For instance on first request the response sent is : 1 2 3
Second request : 4 5 6 and so on.
Now I come to actual problem : I don't know how to do multithreading in a servlet. I have looked through numerous resources and examples but it only has confused me further. Some examples have created threads right in doGet which I think is very wrong, some have created them in the init() method but I dont know how can I pass parameters and get results from the thread if it is declared in the init method (It cannot be a global variable). Then there are examples of servletContextListener but I havent found anything useful or that makes sense.
Can anyone please guide to me a reliable source or just give me some sort of pseudo code to get a solution to my problem. It would be extremely helpful if the answers are in context with the aforementioned scenario.
Thanks
The created thread needs to keep on adding data to the list while the
main thread whenever it gets a request (requests for data keep on
coming periodically) sends the present available list.
If I got you correct, you like to get some data as background service and make them ready for clients once they request them(sounds like harvesting data).
Well, creating thread in web-apps, or generally stuffs come with managed environment is different, creating a thread implicitly would cause of memory leak.
One good solution would having a ThreadPool(either by container context/ndi or create it manually).
AND it MUST be created in a manageable manner, where you would control it by environment related events.
ContextListener is your friend, having a context listener class, like this.
public class dear_daemon implements ServletContextListener,Runnable{
ExecutorService the_pool;
Thread the_evil;
/*following get invoked once the context is called*/
public void contextInitialized(ServletContextEvent sce){
/*initialize the thread-pool, and run evil thread*/}
/*following get invoked once the context is destroying*/
public void contextDestroyed(ServletContextEvent sce){eviling=false;
/*stop evil(this) thread(first), then destroy thread pool*/
}
volatile boolean eviling=true;
public void run(){
while(eviling){
/*run Runnable instance which do data fetching using thread-pool*/
}
}
}
And register the listener in web.xml
<listener>
<listener-class>dudes.dear_daemon</listener-class>
</listener>
Having a class(runnable) which do the data fetching, and invoke it by evil thread, each instance using one thread.
The ContextLisstener helps you correctly shutdown and manage init and hult events by container, using the same thing with servlet init is possible, but make sure you do the same thing about hulting with destroy method of servlet.
If you like to do thread-thing about it, make sure you are doing things thread-safe since you have one thing to store data(a list).
If any synchronization is needed(for example ordering the fetched data), make sure you are doing it right, or you will face with deadlocks, or low-performance code.
If any(probably) IO action is needed for getting data, note java IO is blocking, so set appreciated read and connection timeouts, or switch to NIO if you can handle complex NIO stuffs.
If applying these changes make the environment complex, and you like to do alternative solutions, you may simply extract the data fetching from web-profile and run it as a external daemon-service or applciation, where the applciation will pass the fetched data to the server context using calling one of your CGI/Servlet.
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.
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.
I am running into a situation where I use ThreadLocal static variable to hold a bean that contains various metrics values from different classes during the lifecycle of the request. In a filter I create the bean and set it in a thread local variable and remove it from the thread local variable in the same filter after request has been processed. What I am running into is that the bean containing values from other requests! The only explanation for this is the thread being shared to process multiple requests at the same time. So the question in the title.
While one thread will generally process a single request (speaking about tomcat, for sure), the thread may process multiple requests over time but not w/o finishing the existing request, unless using include/forward alikes.
I'd VERY strognly recommend you to use attribute (setAttribute()) of the said request w/ your bean and use it for profiling. If you can't provide the request to various methods... well you are stuck w/ the ThreadLocal [which is not so bad solution].
Alternatively you can post the code how you install/remove the threadLocal bean.
Keep in mind that you have to to some managing the of that bean as well (it will not be available outside the request).
Edit: forgot to ask: do you use try/finally calling doFilter(...)?
the code should be like that
installBean();
try{
chain.doFilter(req, resp);
}finally{
Bean b = deinstallBean();
useTheMetrics(b);
//potentially, process exception, etc
}
It could also be that your filter is not always called in the sequence you expect it to be. Threads are reused to process multiple requests one after another, so if the removal of the value in the ThreadLocal does not happen, it will still be there when the thread processes its next request.
Yes, you can assume that a single thread will process each request.
Use a finally block to clear (set to null) the ThreadLocal in the filter after processing the rest of the chain. That will prevent data from previous requests from being mingled with the current request.