简体   繁体   中英

Run Quartz Cron Scheduler depending on value fetched from DB

I have a Quartz Cron Scheduler in my Spring Project that executes methods that are declared in the MyCron.java file. In the quartz.xml file, I have configured the beans in this format:

<beans>
<bean id="wakeUsers" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> 
        <property name="targetObject" ref="mycron" /> 
        <property name="targetMethod" value="wakeUsers" /> 
</bean>

<bean id="wakeUsersCronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
        <property name="jobDetail" ref="wakeUsers" />
        <property name="timeZone" ref="timeZone" />
        <property name="cronExpression" value="0 0/5 * * * ?" /> 
</bean>

<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
        <property name="jobDetails">
            <list>
                <ref bean="wakeUsers" />
            </list>
        </property>

        <property name="triggers">
            <list>
                <ref bean="wakeUsersCronTrigger" />
            </list>
        </property>
</bean>
</beans>

It runs fine. The question is that currently I am using 3 machines in production and the cron runs on all the three machines at once. I want to run the cron as per the machine name. When a particular machine name matches with the one in the property, the cron should run otherwise not.

Preferably through Java code, I would like to match my property stored in the DB with my machine's name and then further execute my method.

I have at present implemented the following:

public boolean testRun(){

    try {
        InetAddress ip = InetAddress.getLocalHost();
        String hostName = ip.getHostName();

        if(nodeName.equalsIgnoreCase(hostName)){
            return true;
        }
    } catch (UnknownHostException e) {
        logger.error("Error: Unknown Host");
    }
    return false;
} 

public void wakeUsers() throws Exception{
    if (testRun()) {
        myService.wakeUsers();
    }

}

Any help would be appreciated.

When I encountered this I created a MethodInvokingJobOnSpecifiedMachine which was a bean that would run on all the machines but do nothing if the machine name didn't match.

Then the job detail would be:

  <property name="jobDetail">
      <bean class="foo.bar.MethodInvokingJobOnSpecifiedMachine">
          <property name="machineName" value="DatabaseServer"/>
          <property name="targetObject" ref="mycron" /> 
          <property name="targetMethod" value="wakeUsers" /> 
      </bean>
  </property>

I don't have the implementation any more I'm afraid.

I was able to get to a solution where I used Spring AOP to intercept the method being called by the cron.

I created a class called BaseCron that implements MethodBeforeAdvice interface of the Spring AOP package. I overrode the method before and wrote my logic there that was to be executed before every method call in the MyCrons class.

I then created a proxy bean in the spring config file as:

<bean id="cronsProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
        <property name="target" ref="mycrons" />
        <property name="interceptorNames">
            <list>
                <value>baseCronBean</value>
            </list>
        </property>
</bean>

Therefore before any method in my mycrons was called it was intercepted by the before method present in my BaseCron class where I checked the property machine name where the cron would run.

Cheers!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM