16

I have a quartz job in grails, that needs to be executed in every 5s, but I need this sequentially. In some situations the execution of the job exceeds this 5s, in this case I dont't want to be executed while the previouse exection is not finished. How to configure this in grails?

(Of course the whole magic could be done with a static volatile flag, but is not a very elegant way to do this) (Also how can I configure for the job to be singleton?)

thx

csviri
  • 1,159
  • 3
  • 16
  • 31

4 Answers4

27

Assuming that you're using the grails quartz plugin, you should just be able to set the concurrent property of your job class to false.

From the Quartz Plugin Documentation:

"By default Jobs are executed in concurrent fashion, so new Job execution can start even if previous execution of the same Job is still running. If you want to override this behavior you can use 'concurrent' property, in this case Quartz's StatefulJob will be used"

In more recent versions of the quartz plugin (version 2.0.13 for Grails 3.3.*), that would look like this:

class MyJob {

    static concurrent = false

    void execute() {
        println "Job run!"
    }
}

For older versions of grails/quartz, it would look similar, exception that properties were set with def instead of static:

class MyJob {

    def concurrent = false

    void execute() {
        println "Job run!"
    }
}
Jon Quarfoth
  • 2,129
  • 16
  • 20
  • 1
    Yeah, this is the solution. However I think this not prevents the continual accumulation of tasks into a queue... – csviri Jun 24 '11 at 06:56
  • 1
    So how to prevent the task queue to grow until OutOfMemory occures? – csviri Jun 24 '11 at 08:02
  • Often you want the tasks to queue, one long task shouldn't stop others from executing when the task is a "counting" or "step-by-step" type of task. If this is actually a problem, Quartz probably isn't what you want, what you want is a thread that constantly runs in a loop. If you need to limit it you can put a Thread.sleep(remainingTime) to delay. – Bill K Jul 25 '13 at 16:23
  • @BillK I think that's not such a good idea because you will be hogging a thread forever. – Adriaan Koster Aug 01 '13 at 10:28
  • Hogging a thread forever is rarely an issue unless you need a thousand of them, it's actually the most common way to go. In fact, Quartz allows you (if you choose) to dedicate a thread to one task (hogging it forever). We use this for debugging purposes so that when we see a thread of a given name hung we know what it was supposed to be doing. If you are using many threads then a thread pool may be better, but I'm just saying Quartz may not be the right tool if your problem doesn't fit how it operates. – Bill K Aug 01 '13 at 17:11
  • @Jon Quarfoth Does this approach works for multiple JVM instances too ? Our job is running in all 4 instances, can we prevent it by using your solution ? – Narayan Subedi Mar 12 '19 at 09:54
  • For Grails 3.3 `static` is needed instead of `def`, see my answer. – andysh May 14 '19 at 17:11
  • 1
    With your last edit you made a small copy&paste error. In the second code example (for OLD quartz/grails versions) it should read ``def concurrent = false`` – SebastianH May 13 '20 at 21:28
3

For Quartz-based jobs concurrency is achieved using

static concurrent = false

in the job class.

Note the static in the definition, this is needed instead of def concurrent = false at least since version 2.0.12. See the Quartz documentation.

andysh
  • 339
  • 1
  • 15
3

Make your job class implement StatefulJob instead of Job

Community
  • 1
  • 1
Dónal
  • 185,044
  • 174
  • 569
  • 824
-1

At the and I implemented it without quartz, using spring tasks:

beans = { 
    xmlns task: "http://www.springframework.org/schema/task"

    task.'scheduler'('id':"myScheduler", 'pool-size':"1")

    task.'scheduled-tasks'('scheduler':"myScheduler") {
        task.'scheduled'(ref:"myBean", method:"myBeanMethodToExec", 'fixed-delay':5000)
    }
}

(pool-size 1 I think is even not necessary, but to be sure 100% ;))

Ernesto Campohermoso
  • 7,213
  • 1
  • 40
  • 51
csviri
  • 1,159
  • 3
  • 16
  • 31
  • 1
    You asked a question then selected an answer that didn't address the question. This is not the best answer to address the question you asked, regardless of what you ended up using. – Bill K Jul 25 '13 at 16:18
  • Yes you are right, although I wrote "his not prevents the continual accumulation of tasks into a queue" - I had on my mind this approach, that is in fact solved with this spring scheduler. But you are right that is a good answer on my question. – csviri Aug 07 '13 at 11:00