2013-02-12 2 views
1

Документация Quartz 2 понятна для настройки SimpleJobDetail, так что она выполняет сериализацию (т.е. следующее задание запускает после текущее задание завершает), установив concurrent = false. Документация Quartz 2 также понятна для того, как настроить задание для вызова метода весеннего компонента с помощью InvokeMethodJob. Но неясно, как настроить InvokeMethodJob только для запуска сериализованного (concurrent = false). Я установка InvokeMethodJob как это в конф/Config.groovy:Как настроить сериализованный (неконкурентный) InvokeMethodJob с использованием Quartz 2.x-плагина в Grails 2

import static org.quartz.JobBuilder.* 
import static org.quartz.SimpleScheduleBuilder.* 
import static org.quartz.TriggerBuilder.* 
import org.quartz.impl.triggers.* 
import org.quartz.JobDataMap 
import org.quartz.JobDetail 
import org.quartz.Trigger 
import grails.plugin.quartz2.InvokeMethodJob 
//Begin quartz configuration 
grails.plugin.quartz2.autoStartup = true 
    org{ 
     quartz{ 
      scheduler.instanceName = 'MyScheduler' 
    threadPool.class = 'org.quartz.simpl.SimpleThreadPool' 
    threadPool.threadCount = 20 
    threadPool.threadsInheritContextClassLoaderOfInitializingThread = true 
      jobStore.class = 'org.quartz.simpl.RAMJobStore' 
     } 
    } 
grails.plugin.quartz2.jobSetup.mySchedule = { quartzScheduler, ctx -> 
    def props = new JobDataMap([concurrent:false,targetObject:ctx.myActionService,targetMethod:'myaction',arguments:[true]]) 
    JobDetail jobDetail = newJob(InvokeMethodJob.class) 
     .withIdentity("perform my action") 
     .usingJobData(props) 
     .build() 
    Trigger trigger = newTrigger().withIdentity("every 90 seconds trigger") 
     .withSchedule(
      simpleSchedule().withIntervalInSeconds(90).repeatForever() 
     ) 
     .startNow().build() 
    quartzScheduler.scheduleJob(jobDetail, trigger) 
} 

Однако это позволит несколько потоков для выполнения вызова myActionService.myaction() одновременно. Я хотел бы, чтобы планировщик прекратил дальнейшие вызовы до тех пор, пока не вернется первый вызов.

Я читал о @DisallowConcurrentExecution, но не существует способа применить это (или пример того, как применить это) в определении в conf/Config.groovy.

Лучшее решение, которое я мог придумать было создать новый класс Groovy продлить InvokeMethodJob и пояснение @DisallowConcurrentExecution, как это:

package com.fourgablesguy.quartz2 

import grails.plugin.quartz2.InvokeMethodJob 
import org.quartz.DisallowConcurrentExecution 

/** 
* InvokeMethodJob that is not concurrently executed, serial execution 
* this has the DisallowConcurrentExecution annotation 
*/ 
@DisallowConcurrentExecution 
class SerializedInvokeMethodJob extends InvokeMethodJob { } 

Затем изменить конф/Config.groovy использовать этот новый тип класса Работы:

import com.fourgablesguy.quartz2.SerializedInvokeMethodJob 
... 
JobDetail jobDetail = newJob(SerializedInvokeMethodJob.class) 

Но я, возможно, пропустил что-то менее сложное, что можно было бы сделать вместо этого, чтобы выполнить то же самое с использованием кварца 2, поэтому я разместил это, если у кого-то другое решение.

+1

вы указали threadCount = 20 означает, что на нем не будет одновременных потоков. Может быть, вы можете просто заменить его на 1. – sanghavi7

ответ

2

Лучшее решение, которое я нашел описано в вопросе, аннотировать пользовательский класс InvokeMethodJob с @DisallowConcurrentExecution

THREADCOUNT = 1 может быть вариант, если ваша система только когда-либо делает одну задачу. Если у вас несколько разных заданий, вам потребуется более высокий счетчик потоков, чтобы они могли работать параллельно (некоторые задания, которые вы, возможно, захотите быть неконкурентными). Как только количество потоков превышает 1, вам не гарантируется неконкурентное выполнение для любой работы.

Смежные вопросы