I made an jsf application.This application has a menu containing start,stop buttons.When start is pressed , application starts to get data from web sites, and updates its database.The application also has progress bar for update process.However,this process takes a long time to finish.I want that when i close my browser , it should go on updating database.Besides, when i open it again, i should get previous state.However, this isn't happening.When i close browser the application closes too.How do i do that?
Thanks.
In my case, I would not extend the session life. Instead, create a task and add the object that performs the task into a Queue in an #ApplicationScoped bean and save in database (or any other place) the user that started the job and the status of the job.
When the user logs off (manually logging off or closing the web browser), the task will still be executed because is managed by the whole application (not by a request nor user session). When the user logs in again, he/she could ask to this application queue about the status of the task.
You will need (at least):
An #ApplicationScoped managed bean that will contain and handle the tasks.
A way to handle and execute one or more tasks at the same time. This could be achieved with a ExecutorService or similar technologies. Note: don't dare to manually start new threads by your own, this will only lead to kill your web application server.
An structure to map the user with the tasks he/she has started. It could be mapped with a Map<String, List<Task>> in order that a single user could have more than 1 task at the moment. It would be better to save this in a database (or similar) in order to have a log for these tasks that don't reside in memory. You can even design this in order that if you undeploy the web application or the server suddenly shut downs, you could restart the tasks at hand from a savestate point.
Related
Recently we want to cater the slow loading problem of IIS for first request, after I did some research, I've found that IIS7.5+ has a feature named "Application Initialization" which maybe what I need.
However I have to understand the mechanism before I try to apply it and here is my understanding:
With default IIS setting:
The application pool idle after 20 minutes
The corresponding worker process is killed
First request comes in
IIS starts to create a new worker process
IIS starts to load the application
The client can see after application is loaded
And step 4, 5 makes first request not so responsive.
With Application Initialization set:
The application pool idle after 20 minutes
The corresponding worker process is killed
IIS starts to create a new worker process
IIS starts to load the application through a "fake" request
First request comes in
The client can see after application is loaded
Now the first request is responsive as indeed it is not the first request to the server, sometimes before there was a "fake" request which kicks loading of the application.
What I would like to know is that:
Is my understanding correct?
When application initialization is set, the worker process is still being killed, but a new one is created right after it, is it the case?
That's pretty much how it works. Without Application Initialization, as you mentioned, once the worker process is killed, it is not restarted until a request is sent to it. Upon the first request, a new worker process (W3WP.exe) is started and it starts to load the application. And this cold start of the application is what typically makes the first request less responsive. For eg. if it's an ASP.NET application, the first request triggers the recompilation of the temporary ASP.NET files and this can take several seconds in a moderately large enterprise application.
If you look at the setup of Application Initialization, you will see that there are two main parts to it:
You need to set the startMode of the application pool associated with the website to AlwaysRunning
You need to set preloadEnabled to true on some path (path to the website) on the ApplicationPool
Step 1 is what tells IIS to automatically restart the IIS worker process whenever there is a reboot or IISReset. (You can easily see this in action in TaskManager - do only step 1 and do an IISReset, you should be seeing the existing W3WP.exe process getting removed and a new one is getting created)
Step 2 is what tells IIS to make the initial fake/dummy request that will do all the required initialisation of your web application. For eg. for an ASP.NET application, this essentially will trigger the compilation of all the ASP.NET files, so that the next request - the actual first request to the page does not experience the long delays associated with app initialisation.
While it is true that a traditional approach of keeping using a script to poll the app to prevent it from going idle can do the job, the ApplicationInitalization module makes the job much easier. You can even have IIS issue the dummy request to a custom warmup script that does much more than a simple page load - preloading a cache of several webpages, ahead of time generate/do any task that might otherwise take longer etc.
Official documentations here:
IIS 7.5
IIS 8.0
Your understanding is correct based on my experiences. I first ran into this capability in a performance testing scenario way back in 2014. I was custom coding the ping portion of this into monitoring jobs :O
"The Application Initialization Module basically allows you to turn on
Preloading on the Application Pool and the Site/IIS App, which
essentially fires a request through the IIS pipeline as soon as the
Application Pool has been launched. This means that effectively your
ASP.NET app becomes active immediately, Application_Start is fired
making sure your app stays up and running at all times." - Rick Strahl
Official detailed docs are on the MSDN site, from what I see not much has changed between IIS 7.5 and 8.0 in the way of config.
I'm using the code here to save the image when creating a new user (Persistence chapter)
saveImageWithoutMonitor
SmalltalkImage current saveSession.
writeMutex
^ WriteMutex ifNil: [WriteMutex := Monitor new]
The problem is saving the image takes time and I suspect Seaside on port 8080 is inaccessible and the browser tries to request the next page and it fails to connect. Any better way to do this? Or configure Seaside to delay the page response?
PS. I remember something you had to configure it in Seaside's config page and it would wait.
During saving the image shutdown and startup lists will be processed during which all sockets will be destroyed, hence the connections are canceled. What we do is to fork the image (with OSProcess) and do the saving in the child process. There's even a method that will do this for you, see OSProcess>>saveImageInBackground.
Side note: there are a couple of race conditions when using a forked process like this. If you're dealing with load, it can happen for instance that the child process "steals" the socket from the parent process, which will result in connection timeouts. To prevent this you would need to close the sockets during the fork operation which isn't an easy problem to solve.
I am working on task processing server side application. Use case for application is:
User submit his item.
Server accept item and add to waiting queue, if task executor is busy.
User get that status of item is submitted.
If item is on top of queue server run it as long running task and save result to database.
User refresh application and application get result of execution from database.
It looks like model case, but I do not have experience in this type of applications.
So I search web and found JSR 352, batch processing, which use case is similar but its batch, no single item, so I do not know if it is good solution for my case. But it has nice design, and it is easy to understand.
Also I found this article http://java.dzone.com/articles/design-flexible-and-scalable which looks good.
So are there any other patterns for task processing application? Or what will be best solution?
Also it should be possible to make task executing in multiple threads.
Thanks for point me to right direction :)
I am developing an application that allows users to run AI algorithms on the server remotely. Some of these algorithms take a VERY long time. It is set up such that AJAX calls supply the algorithm parameters and launch a C++ algorithm on the server. The results and status of the computation are tracked via AJAX calls polling status files. This solution seems to work well for multiple users concurrently using the service, but I am now looking for a way to cancel the computation from the user's browser. I have a stop button that stops the AJAX updating service and ceases any communication between the browser and the running process on the server. The problem is that the process still runs, and I would like to free up the server resources when the user cancels the operation. Below are some more details.
The web service where the AJAX calls hit are run under the user 'tomcat' and can be listed by ps -U tomcat. The algorithm executions are all child processes of 'java' and can be listed by ps --ppid ###.
The browser keeps a record of the time that the current computation began (user system time, not server system time).
Multiple computations may be going on at once from users connected from different locations, resulting in many processes under the same name and parent process.
The restful service executes terminal commands via java runtime.exec().
I am not so knowledgeable about shell scripting, so any help would be greatly appreciated. Can anyone think of a way to either use java process object or shell script/awk to locate a process via timestamp (maybe the closest timestamp to user system time..?) or some other way?
Thanks in advance.
--edit
Is there even a way in java to get a handle for a given process if you have the pid...? Doesn't seem like it.
--edit
I cannot change the source code of the long running process on the server. :(
Your AJAX call should be manipulating some sort of a resource (most conveniently a text file) that acts as a semaphore to the process, which in every iteration of polling checks whether that semaphore file has been set to the stop status. If the AJAX changes the semaphore file to stop, then the process stops because your application checks it and responds accordingly. Which in turn means that the functionality needs to be programmed into your Java AI application rather than figuring out what the PID is and then killing it at the OS level. That, of course, assumes you have access to the source code of the app.
Of course, the semaphore does not have to be a file but can be a value in the DB etc., whichever suits your taste and configuration.
I have finally found a secure solution. From the restful java service, using Process p = Runtime.getRuntime().exec() gives you a handle on the running process. The only way, however, to get the pid is through a technique called reflection.
Field f = p.getClass().getDeclaredField();
f.setAccessible(true);
String pid = Integer.toString(f.getInt(p));
How unbelievably awkward...
Anyways, due to the passing of p from the server to the client being impossible, and the insecurity of allowing a remote call to kill an arbitrary server process by a pid passed by parameter, the only logical strategy I could come up with was to write the obtained pid to a process-unique file indicated by the initial client timestamp, and to delete this file upon restful service function return. This unique file can be used as a termination handle via yet another restful service which reads the file, and terminates the process with pid equal to the contents of the file. This
You could keep the Process instance returned by runtime.exec and invoke Process.destroy to kill the subprocess. Not knowing much about your webservice application I would assume you can keep the process instances in a global session map that maps users to process lists. Make sure access to this map is thread-safe. Also it only works if you have one webservice process that allows to share such a global session map across different requests.
Alternatively take a look at Get subprocess id in Java.
Sometimes when IIS restarts the app pool it will start a new instance of my application before the previous instance is shut down completely. This causes me alot of problem so i wonder what i can do about it.
The course of action goes something like this. (spanning about 20 seconds)
Application is running, let's call this instance A.
Restart initializes
A new instance is started, let's call this B (Logged by Application_Start)
Incomming request is processed by instance B, this invalidates all data A has cached.
Timer on instance A is triggered, assumes its cache is valid and writes something invalid into the persistant storage.
Instance A is shut down (logged by Application_End)
Preferable i would like to disable the above behavior completely, IIS should only allow one instance. If not possible, can i in my code detect if other instances is alread running and then wait for it to quit inside application_start? If not possible, what is the best way to work around this?
Disable overlapped recycling:
"In an overlapped recycling scenario,
the process targeted for a recycle
continues to process all remaining
requests while a replacement worker
process is created simultaneously. The
new process is started before the old
worker process stops, and requests are
then directed to the new process. This
design prevents delays in service,
since the old process continues to
accept requests until the new process
has initialized successfully, and is
instructed to shut down only after the
new process is ready to handle
requests."
http://msdn.microsoft.com/en-us/library/ms525803(v=vs.90).aspx