Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
The previous version of this code could sometimes provide a non-positive interval for Ticker.Reset, which causes it to panic. This could happen if a job was already overdue to run when `timeUntilNextRun()` was called, or as time progressed throughout its execution. There are two fixes here: 1. In `timeUntilNextRun()`, only evaluate the current time once and use that throughout so we can be sure we're not skipping safety checks. 2. Switch the `PeriodicJobEnqueuer` loop to use a `time.Timer` instead of a `time.Ticker` since we intend to reset it on every iteration anyway. Step (2) was tricky as it always is when reusing `time.Timer` in Go [1] thanks to its poor design, but I believe I've done that in a safe way here. The reusable timer is now created with 0 duration, ensuring that it will fire quickly, and then the next line always blocks until it fires. This introduces a minimal delay, but it's done to ensure that the first part of the loop (resetting the timer) can always succeed without needing to first try to stop the timer. The only other way the loop can repeat is if we've just received from the timer, so we are guaranteed to be able to safely reset it here. [1]: https://blogtitle.github.io/go-advanced-concurrency-patterns-part-2-timers/
- Loading branch information