I am looking for suggestions or ideas.
There is an external process (or even a browser) that needs to trigger a long-running process via simple web service call that ideally should run in the same container as that web service. We're using Apache ServiceMix. The web service itself shouldn't stay alive for the duration of the long-running process, besides it may just time-out anyway so we want it to return the response normally pretty much right away.
Originally, I was thinking of using ProcessBuilder() to launch the long-running process as just another app but doing this introduces certain OS dependencies and seems like a less then ideal practice anyway. One of the options we considered is starting another thread from the request and just letting the request complete immediately with a response while the long-running thread would keep on going as long as needed. I fear resource hijacking on the container as well as long-running thread's health when its launcher/parent exits losing any reference to that long-running child.
If anyone has any good ideas for how this can be solved in an elegant way, please let me know.
Thank you very much!
I'm guessing here as you didn't provide the version of your servicemix. Though with Camel which is included with servicemix I'd have two routes the first one providing the web service the second one doing the long running process. The second route should use the seda component. This will give you the async call.
Related
For simpler control over application performance I want to use one application wide thread pool. Our app uses Tomcat as web server, Spring and, on the lower level, makes a lot of calls to external APIs. I need some of this external calls run asynchronously, and want to use for this purpose same thread pool as Tomcat uses for client request service.
Firstly, I thought that I can somehow obtain Tomcat thread pool and then use it, but after some googling I haven't found a way to do it.
My second thought was to set custom thread pool for Tomcat and also use it in other places, where I need async calls. But I haven't found how to implement it also.
Any help and advice will be appreciated.
Choose task executor abstractions from Spring.
I am trying to build a webapp with a Vaadin frontend which lets a user upload and process data on our server. The process is quite complicated and is a multi-threaded app (let's call this the 'core'). Whilst designing this app, I thought I could stick everything onto the tomcat server but a colleague of mine told me that natively, Vaadin is RESTful and will thus not run the business process continuously because the application is stateless. He claims that the tomcat JVM will simply go to sleep after running the request and not complete the thread process. Therefore, he suggests that I use RMI to send the data to another process on the same server and process it there instead.
I have a few questions about this:
Is all that he's claimed true? There are some intricacies of implementing Vaadin on Tomcat that I'm not aware of?
More likely I think I'm misunderstanding him and he's actually explaining on why it's better to seperate presentation and business components (which I completely agree with). But on a purely theoretical point of view, would it be possible to stick the multi-threaded core onto the same tomcat server instance as the one running Vaadin?
As far as i know, Vaadin does not use REST services for client-server communication. It is stateful and uses some kind of backing beans.
Regarding your thread issue, if you call your long running task directly from a Vaadin component, it will block the thread processing your request until the task is done. From the browser point of view, you'll have to wait and see the spinning indicator until the process is done (or an exception due to request timeout is thrown).
What you can do is to run your long running task in a separate thread. If you want the new thread to run on the same JVM, you do not need something like RMI.
You can do it by either:
Use an ExecutorService (e.g.: Executors.newSingleThreadExecutor()) and submit a task into
Create a new thread and start it
Do something like: https://vaadin.com/forum/#!/thread/2008536/2010911
Note that you'll probably have to implement some kind of notification mechanism to know when the thread has completed the task.
You can start separate threads from tomcat as needed.
It does not matter what frontend you have for this.
But what's important is to access the vaadin UI components the correct way when you wish to update them from another thread.
For vaadin 7 this has been greatly enhanced, to allow server push out of the box.
In vaadin 6 you had to use some work arrounds for this.
https://vaadin.com/book/-/page/advanced.push.html#advanced.push.running
We use this concept a lot for export and report generation.
- Use click on Export/Report
- On the server we start a (low priority) thread which builds the report/export
- During this, we update a progressbar on the client via server push
- Once the thread has generated the export/report we send it to the webbrowser
If you wish to have a core running always and accepting "jobs" then perhaps you are better served with a job sheduler like quartz or similar.
I would like to ask what is the best approach to run a long process from a java servlet. I have a webapp and when the client do a request it runs a servlet. This servlet should get some parameters from the request and then runs a process. This process may take a long time so I need to run it separately. When this process executed finish, it send an email with the results.
Thanks in advance.
Use a thread pool. Each time you receive a request, create a task and submit it to the thread pool. This will ensure too many requests don't bring the server to its knees, because you'e in control of how many concurrent threads you can have, and how many tasks can wait in the thread pool's queue of waiting tasks.
See the javadoc for Executors and ThreadPoolExecutor.
Though this sounds a bit dangerous that invocation of a servlet spawns a process (without proper throttling capabilities in place), you can spawn a process using Runtime.getRuntime().exec(). Much better would be to use ProcessBuilder to prepare the process arguments and spawn it.
Normally that kind of activities is delegated to another type of application module like a message driven bean and that seems to be the cleanest, and standards compliant solution to me. Although most servers won't complain if you create your own threads (which is forbidden by the standard but rarely enforced) the amount of management needed to set up your own job queue and pooled execution environment isn't really worth it in my opinion.
I see two possibilities to do this:
Create a separate thread for each task (thread pool approach). This is possible, but potentially may create a performance problem.
Create a second application. For instance you can save parameters to DB. Second application will monitor this DB with some interval and do something. Instead DB you can use some message queue manager like WebSphere MQ
Second approach have the advantage: if app not able to process the request now by some reason, the app can return to it later
I am using jetty, version 7.0.1 if that matters.
Sometimes I have some quite long running tasks on a server which I would like to cancel/stop if the client disconnects (in case of GET requests, not e.g. POST file uploads). It seems this is not the case, and that tasks continue to run to
completion.
Perhaps I can use ServletRequestListener.requestDestoryed listener to get notification of such tasks but what is recommended
approach for stoping the request thread? What about releasing resources like database connections, file handles or running tasks
(executor service)?
What is the recommended approach in stopping such tasks as soon as possible?
first I would recommend updating to the latest versions of jetty, we have fixed a ton since 7.0 series
second, your best bet to solve this problem is by design using either jetty-continuations to get async servlet support with servlet 2.5 spec (which is jetty7) or update to servlet 3.0 (jetty 8) and not rely on the get methods of the servlet api to block waiting for a response to send. Instead process the request and then spawn a thread or use an executor future to process the actions, then calling back to the request when you have a payload or success message to return. Reason being that while your in the servlet api blocking on the request process you are consuming resources and threads from your servlet thread pool...you'll be able to scale up much cleaner by using continuations or the async servlets of 3.0...
Also you'll be able to design a proper mechanism for managing these threads and things like timeouts and the proper notification mechanism for exceptional conditions, and it will be testable outside of a servlet container that way.
imo at least :)
I am creating a Java service which will run within a web servlet container (probably Tomcat). One portion of the server will run on its own and will not be initiated by HTTP. I know that when an HTTP call causes an exception, the web container can call it again.
I want to be sure that the part of the server which runs continuously will continue to run, even if it fails. I will handle whichever failures I can manually, but if it all fails I want something to restart it all. Are there any tools that can accomplish this easily? I am already using Spring and Tomcat, so if those can provide it, that is ideal. If not, then how about a good design pattern?
Edit: To clarify, I have a web service which will run in Tomcat. I want to run a separate thread within that service and set it up such that when the thread ends or an un-handled exception occurs, Tomcat (or something else) detects the failure and restarts the web service. I know that typically web containers have threads start from some external call and thus handle failures from those threads. What I want is something which handles a background worker thread.
Not quite clear on the design you have in mind, but it seems to me you need some sort of health check.
You can implement such a mechanism in many ways e.g. open a socket from this process that runs all time and periodically send a message.
If there is no reply then the process failed.
You could restart tomcat or implement a mechanism to restart that process.
Can not tell you more details since you do not specify much on what you are trying to do.
UPDATE:
I think that you should use JMX. It is offered by Spring and Tomcat that you already use.
Just make the process you want to monitor a managed resource and another module can check if it is alive.
If you are running inside a Servlet then as per J2EE spec, you cannot restart the container but, you can use ScheduledExecutorService to continuously monitor that your service is running and if not, then re-start it.
EDIT. More details below
You can call isTerminated() to check if the service still running and add more tasks to it, if the queue is empty.
I may be misunderstanding your problem here, but you might be over-thinking it.
There's nothing stopping you from running multiple Tomcat instances on a single machine. You could then have Server A connect to Server B to pull down information (via a web service of your choosing). This would alleviate the need for an outage on server A to cause an outage on server B (which is what I'm assuming you're trying to avoid).
This is a common way to isolate production environments simply by binding to a separate port. If Tomcat doesn't fit the bill for the service you can always run the application as a service on [insert operating system of choice] and connect to it via a proprietary protocol. Your operating system can handle restarts in that case. Typically I think the multiple Tomcat containers is the easiest approach as it is simple to install and relatively easy to set up.
Good luck, it seems like a fun system administration problem. You also might be interested in checking out Quartz job scheduling as that might fit the bill for an intermittent service.
edit: a little more detail might provide some more detailed answers.
See this post. It's a simple tomcat-watchdog shell script.