Search code examples
c#cronschedulerquartz.net

Quartz.Net with XmlPlugin, use Misfire with overwrite-existing-data


I'm using Quartz.Net (v 3.0.1) for the first time, with the XML Plugin to schedule the jobs and triggers from a XML file.

I need in particular two features:

  • To use the misfire policy, for example FireOnceNow for a certain job scheduled with a cron trigger that had a misfire
  • To load at run time other jobs and trigger (modifying the XML)

Right now I'm stuck with this problem:

I found online various topic (like this one: How to use cron misfire-instruction FireOnceNow with AdoJobStore in Quartz.NET 2.0?) where is explained that <overwrite-existing-data> needs to be at false to use the misfire instructions. And effectively with this setting the job is re-fired if there was a misfire.

The problem is that in this way I can't insert other jobs and triggers in the XML file:

[12:43:25] [Error] Could not schedule jobs and triggers from file
    ~/quartz_jobs.xml: Unable to store Job: 'JobGroup1.TestJob1', 
    because one already exists with this identification.

I don't want every time to delete from XML all the jobs and trigger to add the new one. (I prefer to have in the XML the trace off all my scheduled jobs and triggers)

I'd like to understand what it has to do the <overwrite-existing-data> with the misfire policy in each job.


Solution

  • I'm going to answer my own question 'cause after some research I found the solution.

    My error was to think that the <overwrite-existing-data> setting worked in this way: if I never touched the section of the XML relative to a single Job or his Trigger/s, the scheduler won't never reschedule that Job/Trigger.

    Instead the behaviour is different.

    Indeed, If I modify the XML adding another Job (or anything else) the scheduler notices that the file is changed, and brings all its content (even the existing Jobs and Triggers) and overwrites the ones that were previously stored in the DB. The same thing happens when the scheduler goes down.

    So, if for example my XML is this:

    ...
    <processing-directives>
        <overwrite-existing-data>true</overwrite-existing-data>
    </processing-directives>
    ...
    <job>
        <name>TestJob1</name>
        <group>JobGroup1</group>
        <description>description for TestJob1</description>
        <job-type>TestJob1.TestJob1, TestJob1</job-type>
        <durable>true</durable>
        <recover>false</recover>
    </job>
    <trigger>
        <cron>
            <name>Trigger1</name>
            <group>MyTriggerGroup</group>
            <job-name>TestJob1</job-name>
            <job-group>JobGroup1</job-group>
            <misfire-instruction>FireOnceNow</misfire-instruction>
            <cron-expression>0/5 * * ? * * *</cron-expression>
        </cron>
    </trigger>
    

    and I shut down the scheduler for enough time to produce a misfire, when I restart the scheduler, it will take the TestJob1 and the Trigger1 and overwrite the existing. The information about the misfire will be lost.

    So, like mentioned here How to use cron misfire-instruction FireOnceNow with AdoJobStore in Quartz.NET 2.0? the solution is to set the <overwrite-existing-data> to false.

    In this way every time there is a change in the XML we should to remove all the existings Jobs and Triggers to not get the error

    [12:43:25] [Error] Could not schedule jobs and triggers from file
    ~/quartz_jobs.xml: Unable to store Job: 'JobGroup1.TestJob1', 
    because one already exists with this identification.
    

    To avoid this problem we just add

    <ignore-duplicates>true</ignore-duplicates>