Add custom TriggerContext to ReschedulingRunnable #23715
Closed
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Changes based on:
Allow ReschedulingRunnable to receive a TriggerContext on creation #19475
I needed a way to resume work after a downtime - lets say I need to do daily reports based on what happened during that day. It doesn't matter if the report is delayed as long as it will be there when the system goes back online. With changes, you can easily handle this situation by finding last report date and creating triggerContext based on that time AND passing CronTrigger with argument fixedRate set to true.
It takes away burden of having to manually sync up on startup with custom logic (apart from finding last date), it prevents cases where you have rows with date 10.05, 11.05 and then 14.05, because new Cron fired task for day 14.05 but your catchup logic didn't finish yet the days between 11.05 and 14.05 (unless you write logic to handle "holes" between dates).
Example:
The output for printing execution times will be:
Our cron fired 6 times on startup - TriggerContext set to 60 seconds before "now" and CronTrigger set to fire every 10 seconds. After "catching up" scheduler will work and do it's job like a normal scheduled would do, apart from taking scheduled time when calculating next execution time instead of completion time, which is especially important in cases where you hit huge load and can't keep up with generating lets say these reports but once the load goes down, the reports will be processed and generated.
As for code:
I didn't write any tests. I'm not sure if changes didn't break some tests due to small edits in one or two interfaces (I tried to find all usages but I could miss some). I couldn't properly build project from source without excluding some tasks (-x test -x javadoc -x asciidoctor -x docsZip -x schemaZip -x distZip -x publishMavenJavaPublicationToMavenLocal). I tried to match the original code and style as closely as possible, I also provided some basic documentation for new things based on similar parts in classes. I needed this functionality and thought that making changes directly in Spring was the best way instead of writing custom logic, when most of it is already a part of framework. Adjust the code and add tests based on your preferences or needs.