Hi i am new to grails and I am using quartz plug-in for scheduling jobs. I scheduled job for every 60 sec but it is actually taking more than 60 sec some times So in that case one more threads is started and the first thread is still running So can any one tell me how to execute threads sequentially one by one.
When using the Grails Quartz plugin you can simply set the concurrent property to false to avoid concurrent executions of a Job:
class MyJob {
static triggers = {
...
}
def concurrent = false
def execute(context) {
...
}
}
If you are using Quartz as a plain dependency (not as a Grails plugin) you need to extend StatefulJob (Quartz < 2.0) or set the #StatefulJob and #DisallowConcurrentExecution annotations (Quartz >= 2.0).
Related
I have a grails application and a quartz job running on it. The job contains the below code similar to below .
class MyJob{
static triggers = {}
def printLog(msg){
String threadId = Thread.currentThread().getId()
String threadName = Thread.currentThread().getName()
log.info(threadId+" - "+threadName+" : "+msg)
}
def execute(context)
{
printLog("Before Sync");
synchronized(MyJob){
printLog("Inside Sync");
try{
printLog("Before sleep 20 minutes")
Thread.sleep(1200000)
printLog("After sleep")
}catch (Exception e){
log.error("Error while sleeping")
}
}
printLog("After Sync")
}
}
I have scheduled it to trigger a job every minute
I can see in the logs that one thread is getting the synchronized block and then the other jobs start piling up, waiting for the thread to finish, this is working as expected.
The issue here is the jobs stop after 10 minutes by that time it have created 10 Threads. Out of that one is sleeping for 20 minutes and other 9 are waiting for the 1st thread to release the lock. Why is no new jobs created ?
I saw in some answers I can fix the issue by modifying my triggers section like below
static triggers = {
simple repeatInterval: 100
}
I tried the above option and its still showing only 10 jobs.
From where its taking the default configuration of 10 ?
How can i modify the value to do infinitely ?
I am new to grails and quartz, so I have no idea what is happening.
I think the Grails plugin sets the threadCount to 10 in the bundled quartz.properties file, assuming you're using Grails 3 you can override in application.yml like this:
quartz:
threadPool:
threadCount: 25
Grails 2 - application.groovy
quartz {
props {
threadPool.threadCount = 100
}
}
In general, it's not a a good idea to lock the Job thread with sleeps
If you have a job running a long process you must to split it in several jobs in order to release the Thread as soon as posible
developing application using Grails 2.5.1 i used Quartz plugin , and created a job successfully , but when i inject a service in this job i get org.quartz.JobExecutionException: java.lang.NullPointerException
here is the Job's code:
class EveryMonthJob {
def usersUtilsService
static triggers = {
cron name: 'EveryOneMonthJob', cronExpression: "* 31 2 L * ?"
}
def execute() {
usersUtilsService.testMe() // getting the exception here
}
}
There are any number of reasons that might not work. If you are creating an instance of the job yourself (as opposed to Spring creating the instance and subjecting it to dependency injection), that would explain why the reference is null. Another explanation could be that you have the property name wrong.
See the project at https://github.com/jeffbrown/sherifquestion. That is a Grails 2.5.1 app that does just what you are describing and it works fine. See https://github.com/jeffbrown/sherifquestion/blob/e0179f836314dccb5f83861ae8466bfd99717995/grails-app/jobs/demo/EveryMonthJob.groovy which looks like this:
class EveryMonthJob {
// generally I would statically type this property but
// am leaving it dynamically typed top be consistent with
// a question being asked...
def usersUtilsService
static triggers = {
simple repeatInterval: 5000l // execute job once in 5 seconds
}
def execute() {
usersUtilsService.testMe() // this works fine
}
}
I have grails 1.3.7 and quartz plugin 0.4.2 for cron jobs.
class MyJob {
static triggers = {}
void execute() {
//some doings.
}
}
Somewhere in my code I have dynamic scheduling of my job like that:
MyJob.schedule(cronExpression)
Every time I schedule new cron job it creates new one and it works together with previously created jobs. But I want to replace old cron jobs of MyJob with new one each time.
Maybe I was wrong in my understanding but I tried to add
def concurrent = false
It didn't help.
Is there any way to stop all jobs of some job class?
Thank you!
UPD: As I understand there is no such thing as InterruptableJob in this version of quartz plugin. Am I right?
Finally I've found way how to unschedule job and schedule another one.
First I've added a group for job:
class MyJob {
def group = 'jobGroupName'
static triggers = {}
void execute() {
// some stuff
}
}
Also I've found JobManagerService inside plugin with very useful methods. But I was looking into source codes to get how it works correctly. After some time my solutions become in next code (maybe it's raw yet, but it works):
class MyService {
def jobManagerService
def rescheduleJob() {
def job = jobManagerService.getJob('jobGroupName').first()
Scheduler scheduler = jobManagerService.quartzScheduler
Trigger trigger = scheduler.getTriggersOfJob(job, 'jobGroupName').first()
if (!jobManagerService.unscheduleJob(trigger.group, trigger.name)) {
log.warn('Failed during unscheduling job')
} else {
MyJob.schedule(newCronExpression)
}
}
}
It's not clear sometimes which name and group required in service methods. So debug and sources helped me with this.
I'm having trouble getting my Quartz Job in Grails to run concurrently as expected. Here is what my job looks like. I've commented out the lines that use the Executor plugin but when I don't comment them out, my code works as expected.
import java.util.concurrent.Callable
import org.codehaus.groovy.grails.commons.ConfigurationHolder
class PollerJob {
def concurrent = true
def myService1
def myService2
//def executorService
static triggers = {
cron name: 'pollerTrigger', startDelay:0, cronExpression: ConfigurationHolder.config.poller.cronExpression
}
def execute() {
def config = ConfigurationHolder.config
//Session session = null;
if (config.runPoller == true) {
//def result = executorService.submit({
myService1.doStuff()
myService2.doOtherStuff()
//} as Callable)
}
}
}
In my case, the myService2.doOtherStuff() is taking a very long time to complete which overlaps the next time this job should trigger. I don't mind if they overlap which is why I explicitly added def concurrent = true but it isn't working.
I have version 0.4.2 of the Quartz plugin and Grails 1.3.7. Am I doing something wrong here? Seems like a pretty straightforward feature to use. I'm not opposed to using the Executor plugin but it seems like I shouldn't have to.
I'm not sure it matters but the cronExpression I'm loading from config in this case is meant to execute this job every minute: "0 * * * * ?"
Apparently, there was a hidden config that I was not aware of that was keeping this from working. In my conf folder there was a file called quartz.properties which contained the following property:
org.quartz.threadPool.threadCount = 1
After increasing this number, my job was triggering even when it had not finished the previous execution.
I have an application using Grails Quartz plugin. I need to have two jobs to have multiple instances running, but have separate limitation on number of threads to be used for each job. As far as I understand, I need separate Thread Pools, which is possible by having separate schedulers. However, I cannot figure out how to create multiple schedulers with Quartz plugin.
Assuming you want to use different triggers to start the job multiple times. this works for me.
class MyJob {
static triggers = {
cron name: 'trigger1', cronExpression: "0 30 12 ? * WED"
cron name: 'trigger2', cronExpression: "0 30 12 ? * SAT"
}
def execute() {
// execute task, do your thing here
println "Job executed"
}
}
Finally, about concurrent tasks.
This is from the plug-in page:
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.
Quartz plugin 2.0.13
According to the official documentation :
Multiple triggers per job are allowed.
For instance,
class MyJob {
static triggers = {
simple name:'simpleTrigger', startDelay:10000, repeatInterval: 30000, repeatCount: 10
cron name:'cronTrigger', startDelay:10000, cronExpression: '0/6 * 15 * * ?'
custom name:'customTrigger', triggerClass:MyTriggerClass, myParam:myValue, myAnotherParam:myAnotherValue
}