Reschedule dynamic recurring tasks when they are updated - #774
Closed
wintan1418 wants to merge 1 commit into
Closed
Conversation
wintan1418
force-pushed
the
pick-up-dynamic-recurring-task-updates
branch
3 times, most recently
from
July 30, 2026 11:47
81bdc96 to
f5bab54
Compare
The scheduler's polling cycle only handled created and deleted dynamic tasks. A task whose schedule, class, arguments or any other attribute changed fell through both checks, so the scheduler kept firing on the old definition until the process was restarted. Keep the previously loaded snapshot of dynamic tasks and compare each reloaded task's updated_at against it, cancelling and rescheduling any task that changed. Fixes rails#738
wintan1418
force-pushed
the
pick-up-dynamic-recurring-task-updates
branch
from
July 30, 2026 11:59
f5bab54 to
c2e5d68
Compare
Member
|
Hey @wintan1418, thanks for this, but this is expected behaviour. Check this comment: #739 (comment) |
Contributor
Author
|
Thanks @rosa — makes sense, and sorry I missed the earlier discussion on #739. Closing this one. Since it's tripped a few people now, I've opened #777 adding a short note to the README's dynamic tasks section spelling out that in-place updates aren't picked up and that unschedule + schedule again is the way to update a task. |
rosa
pushed a commit
that referenced
this pull request
Jul 30, 2026
The scheduler only detects dynamic tasks being created and deleted, so updating a SolidQueue::RecurringTask record in place isn't picked up until a restart. This is by design: the documented way to update a task is to unschedule it and schedule it again. This wasn't stated in the README and has caused some confusion (#738, and the closed #739 and #774), so spell it out in the dynamic tasks section.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Fixes #738
Problem
When dynamic recurring tasks are enabled, the scheduler's polling cycle (
Scheduler::RecurringSchedule#reschedule_dynamic_tasks) only handles two cases:schedule_created_dynamic_tasks— rows whose key isn't scheduled yetunschedule_deleted_dynamic_tasks— scheduled entries whose key is no longer in the DBA task whose key exists in both places falls through both checks, so any update to its
schedule,class_name,arguments,queue_name, etc. is silently ignored: the scheduler keeps firing against the pre-update definition until the process restarts.Fix
Keep the previously loaded snapshot of dynamic tasks across each polling cycle and compare every reloaded task's
updated_atagainst it. Any task that changed gets its in-memory scheduled entry cancelled and rescheduled from the fresh record, mirroring what a delete + create with a polling cycle in between would have done.Testing
Added a regression test that starts a scheduler with a dynamic task on an hourly cadence, updates it to
every secondwhile the scheduler is running, and asserts jobs get enqueued without a restart. The test fails onmainand passes with this change.