How can I initiate a task when another one ends?

I have two jobs, think of them as super simple jobs that just print a line and have no triggers or timeouts. They work great when I call them from the controller class via:<name of my class>Job.triggerNow()

I want to be able to start one job and, as it completes, start subsequent other jobs.

I tried to use quartzScheduler

, but I can't get JobDetail

from my classes to work, so I'm not sure if this is the correct way to do it. I also want to pass some results from the first job to the second.

I know I can run the second job as the last line in my first job execution method, but this is not desirable as it is not technically part of the first job and does not combine things more than I would like.

Any help would be greatly appreciated. thank


source to share

3 answers

It looks like what you are after is an asynchronous "pipeline" of work in which there are different workers, all of which are on the same line and passing data to be processed from one to the other. This architecture is surprisingly flexible and applies to a large number of very common applications.

The best way to find such an architecture with Grails is to use a message queue like RabbitMQ for example with a series of queues (one for each step in the pipeline) and then the controller puts the messages on the first step of the pipeline.

Then you have a worker (just a service in a Grails app if you're using the great RabbitMQ Grails plugin ) listen to the queue that the jobs are running for them. When a job enters a queue, the worker drops the job, processes it, and then puts the message on the next hop queue in the pipeline.

I have found this to be the best way to architect almost any asynchronous pipeline, as it allows you to scale each piece individually as needed and does not have too much overhead. There are also ways to decouple the jobs from the need to know about the next step in the pipeline, but I've found that in most cases this is really unnecessary and just adds unnecessary complexity.

Quartz is great for jobs that need to run on a schedule, but the pipeline handles things much better since it comes in a scalable way.



Please see @ JobListener

you can use

public void jobWasExecuted(JobExecutionContext context,
            JobExecutionException jobException);




I have built something similar to this in my web application using the queued messaging technique with Redis. I just define a dependency structure for all jobs and have a main job with the sole purpose of monitoring / updating the state of other jobs and running dependent jobs if needed.

Each job should report the execution / completion / cancellation status using a Redis queue. The master job issues every message to the queue and processes it correctly.



All Articles