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.
Related
This question already has answers here:
How to run a background task in a servlet based web application?
(5 answers)
Closed 5 years ago.
I've been searching all over google and stackoverflow about whether can the server send auto email , for example every monday, using servlet without any user interactions.
AT the moment, user has to log in and codes gets excuted.
What I want is the server to excute the code at specific time and user don't have to log in and don't even see that.
I don't want to relay on users, I want to relay on server instead.
You need to have a non interactive thread in your server. Ideally, this thread should be started by a ServletContextListener, to be sure that it will be active even before first client connection.
You can either build something from scratch or use a dedicated tool such as the excellent Quartz scheduler, that will do the boiler plate code for you.
Once you have the scheduler, you just need to be able to send mail to a mail server via SMTP. Here again, you can implement the protocol by hand (SMTP is not that hard), but if you do not want to re-invent an oval wheel where round ones are already around, use the javamail API from the Java EE SDK, or another third party library such as the one provided by Apache
As long as your server application is running, you can use Quartz to schedule your email-sending process.
Check here: https://quartz-scheduler.org/documentation
You should be able to do what you are after by setting up another application which executes as a service. Underneath, this application could use something such as Quartz to manage the scheduled events.
You could keep it in sync with the web application through the use of some database. This approach should allow for the automation of email transmission.
You can use Quartz to scheduler a job to run at a specified date and time.
there are two types of triggers in Quartz 2
SimpleTrigger - this one Allows to set start time, end time, repeat interval.
CronTrigger - it Allows Unix cron expression to specify the dates and times to run your job.
You can get the Quartz library from official website or from maven repository.
In House Solution
If you dont wanna use any third party jar for this purpose,there is one more way.As of J2SE 1.3, Java contains the java.util.Timer and java.util.TimerTask classes that can be used for this purpose
See Also
Quartz 2 trigger examples
Background threads
You need to have a background thread running and waiting for the next time an email is to be sent. Java 5 adds some classes to make such background threads and tasks quite easy.
Some other answers mentioned the Quartz library. I've not used that, and it may have nice features. But it is certainly not necessary for your purpose. The classes built into Java suffice.
ServletContextListener
Create a subclass of ServletContextListener. This class is guaranteed to be called before any servlet request is processed. So this is the place to initialize objects used by your web app. This class is also called when your web app is shutting down.
ScheduledExecutorService
In your servlet context listener, when your web app launches, instantiate a ScheduledExecutorService. This class uses a thread pool to run tasks in the background. You specify an initial delay before first run (optional), and specify how often to repeat the task.
In your servlet context listener, be sure to shutdown your ScheduledExecutorService when your web app is shutting down. If you do not, the background threads in the pool continue to live. The java process launched on your host operating system to run your servlet container will continue rather than exit.
Be sure to add a try-catch around your task. Any Exception reaching your ScheduledExecutorService causes the service to silently stop. See this funny post (caution, naughty language).
Search StackOverflow for more details and examples. This Question is basically a duplicate, so I kept this Answer brief.
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.
I have a scenario to ask regarding utilizing the EJB Timer Service.
Use case as follows:
The system should be able to schedule a task that will poll/ask our subversion repository for files changes using some particular timestamp.
The idea is that whenever the scheduled task is about to run, it will execute command against a particular svn repository.
For this particular purpose, I will not call any external process but will use the 'pure' java way of using the SVNKit java library http://svnkit.com/
My only concern is this:
Is it a good idea to use the EJB Timer Service to execute task that will call external processes? My way will use a 'pure' java way but in other scenario such as calling a batch file/command line/external executable directly into the timer service logic.
I worry about the effects of server memory use/performance etc.
Is this a good idea?
The other thought that I am thinking is to just create a 'desktop' application in the server using client based technology such as SWT/Swing that will do the polling and then code the logic there but this will mean that I need to manage two applications. The 'desktop' app that will poll and the 'web' user interface that I will create in Glassfish.
I am leaning towards doing everything in the App server of my choice which is glassfish.
I have used EJB Timer before but it only calls against the database without calling any extenral service and it's just that this scenario came up so I raised a question here to gather more thoughts from those who have experienced doing this.
Any thoughts?
In theory, EJBs aren't supposed to depend on external I/O since it interferes with the container/server's management of bean instances, threads, etc.
In practice, this should work if you take precautions. For example:
isolate the function to its own EJB (i.e., a stateless session bean that only handles these timers) to avoid instance pooling issues
use timeouts while waiting for commands to avoid hung processes from hanging all server threads
ensure that you don't schedule timers so that you have multiple OS commands run simultaneously
Keep in mind that EJB 3.0 timers are persistent (vs EJB 3.1 timers, which have the option of being non-persistent), which means:
They can run on any server in a cluster. If you have multiple machines in your cluster, you need to ensure that they are all capable of running the command.
They survive server restarts. If you schedule a timer to run but the server crashes before it can, it will run when the server restarts. This can cause particular problems for interval timers (all missed timers will fire repeatedly) and if you don't carefully manage existing times (you can easily create redundant timers).
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.
I have a local web app that is installed on a desktop PC, and it needs to regularly sync with a remote server through web services.
I have a "transactions" table that stores transactions that have been processed locally and need to be sent to the remote server, and this table also contains transactions that have retrieved from the remote server (that have been processed remotely) and need to be peformed locally (they have been retrieved using a web service call)... The transactions are performed in time order to ensure they are processed in the right order.
An example of the type of transactions are "loans" and "returns" of items from a store, for example a video rental store. For example something may have been loaned locally and returned remotely or vice versa, or any sequence of loan/return events.
There is also other information that is retrieved from the remote server to update the local records.
When the user performs the tasks locally, I update the local db in real time and add the transaction to the table for background processing with the remote server.
What is the best approach for processing the background tasks. I have tried using a Thread that is created in a HTTPSessionListener, and using interrupt() when the session is removed, but I don't think that this is the safest approach. I have also tried using a session attribute as a locking mechanisim, but this also isn't the best approach.
I was also wondering how you know when a thread has completed it's run, as to avoid lunching another thread at the same time. Or whether a thread has ditched before completing.
I have come accross another suggestion, using the Quartz scheduler, I haven't read up on this approach in detail yet. I am going to puchase a copy of Java Concurrency in Practice, but I wanted some help with ideas for the best approach before I get stuck into it.
BTW I'm not using a web app framework.
Thanks.
Safest would be to create an applicationwide threadpool which is managed by the container. How to do that depends on the container used. If your container doesn't support it (e.g. Tomcat) or you want to be container-independent, then the basic approach would be to implement ServletContextListener, create the threadpool with help of Java 1.5 provided ExecutorService API on startup and kill the threadpool on shutdown. If you aren't on Java 1.5 yet or want more abstraction, then you can also use Spring's TaskExecutor
There was ever a Java EE proposal about concurrency utilities, but it has not yet made it into Java EE 6.
Related questions:
What is the recommend way of spawning threads from a servlet?
Background timer task in a JSP web application
Its better to go with Quartz Scheduling framework, because it has most of the features related to scheduling. It has facility to store jobs in Database, Concurrency handling,etc..
Please try this solution
Create a table,which stores some flag like 'Y' or 'N' mapped to some identifiable field with default value as 'N'
Schedule a job for each return while giving loand it self,which executes if flag is 'Y'
On returning change the flag to 'N',which then fires the process which you wanted to do