Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Triggers fired milliseconds too early #83

Closed
herrmic opened this Issue · 4 comments

3 participants

@herrmic

I experienced triggers being fired 1 millisecond ahead of schedule.
In my application I create among others simple triggers that should fire once at specified time. I use TriggerBuilder.StartAt method to set the time. Method's documentation says:

the Trigger will NOT fire before this time, regardless of the Trigger's schedule

However, in the log files I sometimes see that task scheduled for 2012-11-28 07:12:24 runs at 2012-11-28 07:12:23,999. This clearly breaks the method's contract. And it breaks the application.
It is very hard to reproduce, it occurs only on one machine and not all the time.

I looked around Quartz code and I think that problem is caused by the following line in the QuartzSchedulerThread class:

while (timeUntilTrigger > TimeSpan.FromMilliseconds(2))

It seems that this implementation is fine with firing triggers 1 or 2 milliseconds before schedule. This is however not what the documentation/specification says.

@lahma
Owner

I'd say this is by design. It's probably impossible to ever get millisecond precision of fire time with all locking and extra checks that need to be done. If you are OK with running possible a bit after the schedule but not before, should you schedule you runs a couple milliseconds later?

@herrmic

I think that this issue is relatively easy to fix. QuartzSchedulerThread class has a loop that is exited when it's time to fire a trigger. Problem is that the code allows exiting the loop up to 2 milliseconds before firing time (the code is very explicit about this, it uses TimeSpan.FromMilliseconds(2)). I think that hidden assumption here is that it will take at least 2 milliseconds before job code is actually reached. However, on fast computers, job code is executed quicker.

The easiest way to fix the bug is to remove that additional loop exit condition and don't exit the loop ahead of schedule. More complex one is to wait before actually calling the job (spin-wait perhaps, if it's sensible to spin for 1 or 2 milliseconds).
I know that millisecond precision is not possible. But while it's perfectly acceptable to have code launched few milliseconds after the schedule (it is never possible to predict what will slow us down anyway), being run too early can be disastrous.

I can fix this myself and send you a patch if that's OK.

It is possible to schedule my jobs few milliseconds later. However, the exact value of "few" depends on implementation detail which is not public or guaranteed to remain unchanged. It would be workaround for a bug which I think is easily solvable.

@Petoj87

I have to say its NOT ok for it to fire to early this can have devastating effects, in my case it was ok to be to late so i just added a few milliseconds for good measure but this has to be fixed..

By design i would say its ok to be to late but its not ok to be to early.

How upset would you be if you arrived at the train station only to realize that the train left early?

@lahma lahma added this to the 2.2.5 milestone
@lahma lahma closed this in b87f209
@lahma
Owner

Even though I'm fine with the train leaving two milliseconds ahead of time (kidding here), I've now pushed a change to check against TimeSpan zero instead of the 2 millisecond window.

@lahma lahma modified the milestone: 2.3, 2.2.5
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.