I am working on a new functionality for a multi-tenancy web-app, which allows the admin to start a potentially very long running process (ca. 1 - 5 min) by the click of a button in the admin panel.
However it is crucial that such a task can only be executed ONCE at a time for each tenant. Of course we can disable the button after a click, but we cannot prevent the admin (or another admin) from opening another browser tab and clicking the button again.
Is there any existing library which allows us to:
Uniquely identify a job (e.g. by an id like "tenant_001_activation_task")
Start the task in the background
Query if such a task is already running in the background and if so reject any further calls to this function.
I already had a look into quartz and the Spring TaskExecutor. However these two seem to mainly focus on scheduling tasks at a given time (like a cronjob). What I'm looking for is a solution for running and monitoring a background job at any time programmatically.
If you decide to use Quartz, you can simply annotate the relevant job implementation classes with the #DisallowConcurrentExecution annotation.
Please note that this annotation is effective on the Quartz job detail level, not on the job implementation class level. Let us say you have a job implementation class com.foo.MyTenantTask and you annotation this class with the #DisallowConcurrentExecution annotation. Then you register 2 jobs that use this job implementation task - tenant_001_task and tenant_002_task.
If you run tenant_001_task and tenant_002_task, they will be allowed to run concurrently because they are different jobs (job details). However, if you attempt to run multiple instances of tenant_001_task concurrently, Quartz will only execute the first instance and the other instances will be queued up and wait for the first instance to finish executing. Then Quartz will pick one queued instance of tenant_001_task and execute it and so on until all queued up instances of tenant_001_task have been executed.
On the other hand, Quartz will not prevent concurrent execution of tenant_001_task and tenant_002_task instances since these represent different jobs (job details).
Quartz provides various (local, JMX, RMI) APIs that allow you to obtain the list of currently executing jobs, list of all registered jobs and their triggers etc. It will certainly allow you to implement the scheduling logic you described.
If you are building an app to manage and monitor your Quartz jobs, triggers etc., I recommend that you take a quick look into our product called QuartzDesk. It is a management and monitoring GUI for all types of Java Quartz-based applications. There is a public online demo and if you want to experiment locally, you can request a 30-day trial license key. If you need to interact with your Quartz schedulers programmatically (and possibly remotely), you can use various JAX-WS service APIs provided by QuartzDesk.
Related
Just looking at the Activiti admin app and I'm wondering what the differences are between Deployments, Definitions, Instances, Tasks and jobs.
Ive had a go at explaining what I think these do?..
Any help much appreciated.
Deployments - instances of Activiti Engine?
Definitions - ??
Instances - ??
Tasks - Outline of different tasks that can be applied to various processes. Such as Decision Tables, User tasks?
Jobs - List of current jobs/processes in action?
The activiti APP provides out of the box some generic UIs for generic "Tasks" that are usually required in a BPM system.
So the following are some very simple answer to your questions:
Applications being deployed.. they all run on top of the same engine (we are changing that in Activiti Cloud). Applications are logical groups of Process Definitions, Decision Tables, Forms, etc.
Definitions: process, decision tables, forms definitions
Process Instances: running business processes
Tasks: User tasks generated by process instances (every time that a business process hits a UserTask node, it will create a new Task here). Tasks are always assigned to real people or groups of people.
Jobs: Async jobs that are created by Async nodes inside the process definitions, also used for timers. Imagine a DB (by default) scheduler like Quartz here to do async executions. Jobs are usually used for System to System interactions. When you have long running system to system interactions you might need to execute that in an asynchronous fashion and that is where jobs come into action.
Hope that helps
We need to monitor the status of quartz jobs by only having access to the database. Does quartz offer a way to achieve this?
Reading the documentation, in the Trigger class we have TriggerState which defines various states, ERROR and COMPLETE among others.
But during regular execution, the CompleteExecutionInstruction is always NOOP. It doesn't matter if I throw an exception or execute completely. I was expecting something like COMPLETE if I was successful or ERROR if I threw an exception.
Does anyone have any experience with this?
Trigger state in no way reflects the last execution status of your job so you cannot expect the trigger state to be COMPLETE or ERROR.
If you want to monitor your jobs, I recommend that you look into the Quartz JobListener interface. This interface allows you to intercept and process all job execution events that you may be interested in. For example, you may want to implement a job listener that stores the intercepted job execution events in a database and then you can query this database to obtain the last job execution status of your jobs etc.
You may also consider using an existing Quartz scheduler, job and trigger management and monitoring tool. I am the original author of QuartzDesk which is one of these tools. QuartzDesk is a completely non-intrusive tool that does not require you to modify your application code in any way, and it can work with all types of Java applications and nearly all Quartz versions. There is a public online demo that you can register to, try and see for yourself if the tool satisfies your requirements. When it comes to monitoring, the QuartzDesk GUI displays a so-called health indicator next to each job and trigger. This indicator depicts the status (success, error, veto) of the last 10 job/trigger executions so you can quickly see if there are any jobs that failed recently etc. You can also access complete execution history of individual jobs and trigger. If you want to be notified of any job execution related event, you can create an execution notification rule that will send you a notification message (IM, SMS, email, Slack, HipChat, SNMP Trap, ...) when a configured condition is met. I am attaching a screenshot of the GUI showing job health indicators and the selected job's execution history.
.
I am using Spring Batch in a web application. The jobs are run by a custom TaskExecutor that manages the submitted Runnables in a queue and executes them one after another. Thus many jobs have the status STARTING or STARTED for a long time.
Now it happend that the server was shutdown while there were still jobs in the queue. After a restart of the server the jobs are still marked as running, but instead they should be abandoned.
How can this be done?
Spring Batch provides no tools out of the box for something like this. The reason for that is that this typically requires a human decision of some kind on what conditions this type of behavior is appropriate.
That being said, in your case, if you are not running in a clustered environment, you could create a component that, on the initialization of the application context, examines the job repository and updates the statuses as required (similar to how you can initialize a datasource on startup).
Asynchronous jobs such as download scores from the website, or send emails after completion of some critical tasks.
Rightnow we when we download some scores, we have to wait on the current page to get the response page or to get file downloaded.
Is there a possibility that i can click on download scores and it happens in the background so that i can navigate to other parts
of the website, and in the mean-time check the status of the job. Or Schedule some job later in the future and get its execution results
via email.
Ours is a struts 2 webapplication with Hibernate 3.5 ORM. After browsing into some java scheduling libraries, got some info on Quartz.
But is Quartz the right library for the above requirements or any other library that i can try for?
Please guide me in the right direction.
You will need some sort of asynchronous processing support. You can use:
quartz-scheduler - this library is very comprehensive and allows you to schedule all sorts of jobs. If you want to use it only for the purpose of scheduling jobs in the background and run them immediately, might be an overkill
use thread pool, see Executors class
jms queue can listen on requests and process them asynchronously in mdbs
Finally you can take advantage of #Async/#Asynchronous support in spring or ejb
Then you mut somehow restore the results. Depening on whether you want to deliver them directly in the browser or via e-mail:
every time you are rendering a page, check whether there aren't any completed/in progress jobs. If there are some completed jobs, display an extra link on the page somewhere (sort of notification). If the job is in progress, start an ajax request and ask every other second or use long-polling/comet to receive the result immediately
if you want to send results by e-mail, just send it after the job finishes. Much simpler but less user-friendly IMHO.
Quartz is certainly one way to do that - and works well if you want to schedule a job to run at a particular time or with a particular frequency.
If you just want to kick something off in the background in response to a user action, and check its status, there are a few other ways to do it which may be better suited to this pattern:
the java.util.concurrent package: you can set up a ThreadPoolExecutor and submit tasks to it that implement Callable. You get back a Future<T> object that you can check for completion (isDone) and get its result when complete (get).
with EJB or Spring, there is also a concept of a (session) bean method being #Async or #Asynchronous, which return a Future<T> as well and behave as above. Basically this just abstracts away the thread-pool creation and management from your code, and moves it into the container or framework.
In my application I need to have periodically run background tasks (which I can easily do with Quartz - i.e. schedule a given job to be run at a specific time periodically).
But I would like to have a little bit more control. In particular I need to:
have the system rerun a task that wasn't run at its scheduled time (i.e. the server was down and because of this the task was not run. In such a situation I want the 'late' task to be run ASAP)
it would be nice to easily control tasks - i.e. run a task on demand or see when a given task was last run or reschedule a given task to be run at a different time
It seems to me that the above points can be achieved with Spring Batch Admin, but I don't have much experience in this area yet. Also, I've seen numerous posts on how Spring Batch is not a scheduling tool so I'm becoming to have doubts what the right tool for the job is here.
So my question is: can the above be achieved with Spring Batch Admin? Or perhaps Quartz is enough but needs configuring to do the above? Or maybe I need both? Or something else?
Thanks a lot :)
Peter
have the system rerun a task that wasn't run at its scheduled time
This feature in Quartz is called Misfire Instructions and does exactly what you need - but is a lot more flexible. All you need is to define JDBCJobStore.
it would be nice to easily control tasks - i.e. run a task on demand or see when a given task was last run or reschedule a given task to be run at a different time
You can use Quartz JMX to access various information (like previous and next run time) or query the Quartz database tables directly. There are also free and commercial management tools basex on the above input. I believe you can also manually run jobs there.
Spring Batch can be integrated with Quartz, but not replace it.