Skip to content

feat: reactive character scheduling via self-rescheduling CharacterBatchJob#678

Merged
herpaderpaldent merged 4 commits into
4.xfrom
feat/reactive-character-scheduling
May 27, 2026
Merged

feat: reactive character scheduling via self-rescheduling CharacterBatchJob#678
herpaderpaldent merged 4 commits into
4.xfrom
feat/reactive-character-scheduling

Conversation

@herpaderpaldent
Copy link
Copy Markdown
Contributor

Summary

Replaces fixed 1-minute cron polling with a self-perpetuating queue cycle. Once a character batch starts, it automatically re-schedules itself after REFRESH_DELAY_MINUTES (5 minutes), keeping characters continuously fresh without hammering the scheduler.

Changes

CharacterBatchJob

  • Add REFRESH_DELAY_MINUTES = 5 constant
  • Add $reschedule constructor param (default false) — controls whether finally() re-dispatches
  • Store the originating queue name on BatchUpdate so re-dispatched jobs stay on the same queue
  • shouldDiscardUpdate() simplified: only discards if the batch is still is_pending (the hour-window guard was appropriate for fixed polling, not needed with self-scheduling + ShouldBeUnique)

UpdateCharacter (bootstrap/catchup job)

  • Rewritten to only dispatch CharacterBatchJob (with reschedule: true) for characters that:
    • Have never been updated, OR
    • Whose last batch finished > 10 minutes ago (stale/fallen-off)
  • 2-second stagger delay per character to spread initial queue load
  • Schedule changed from * * * * **/30 * * * * (catchup only, not primary driver)

Migrations

  • add_queue_to_batch_updates_table — new nullable queue column on batch_updates
  • update_character_schedule_to_catchup — updates UpdateCharacter cron to */30 * * * *

Tests

All 13 targeted tests pass; full 564-test suite passes; PHPStan clean.

…tchJob

Replace fixed 1-minute cron polling with a self-perpetuating queue cycle:

CharacterBatchJob changes:
- Add REFRESH_DELAY_MINUTES = 5 constant
- Add $reschedule constructor param (default false)
- Store queue name on BatchUpdate so re-dispatched jobs stay on the
  same queue as the original
- finally() callback dispatches a delayed self-reschedule when
  $reschedule = true (after REFRESH_DELAY_MINUTES)
- Simplify shouldDiscardUpdate(): only discard if still pending;
  the fixed-interval hour-window guard is no longer needed

UpdateCharacter changes:
- Rewritten as bootstrap/catchup job: dispatches CharacterBatchJob
  (with reschedule: true) only for characters that have never been
  updated OR whose last batch finished > 10 minutes ago
- 2-second stagger delay per character to spread initial load
- Removed CronExpression dependency and interval calculation
- Schedule changed from every minute to every 30 minutes (catchup only)

Migrations:
- Add queue column to batch_updates table
- Update UpdateCharacter schedule expression to */30 * * * *

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@what-the-diff
Copy link
Copy Markdown

what-the-diff Bot commented May 26, 2026

PR Summary

  • Upgraded Storing Process fer Unfinished Jobs: We've baked a change into the system that adds a new spot fer awaiting orders in the 'batch_updates' ledger, so our friendly jobs aren't lost in the ether.
  • Restructured Timing fer UpdateCharacter Work Orders: Our automated mate 'UpdateCharacter' will now be takin' a breather, his orders now come every 30 mins, not every minute. Less bother fer our crew, more efficient.
  • Introduced a Mini-Timeout Variable: We've named a constant timer, 'REFRESH_DELAY_MINUTES' - a short 5 min break fer our engine room, the 'CharacterBatchJob' class. Gives us space to breathe.
  • Updated Construction o' CharacterBatchJob: This creation process now comes with the option of a 'reschedule' flag. More control, more power, (insert mad laughter)!
  • Revamped Job Execution Strategy: We've made it so our job dispenser can hold off some jobs if the new 'reschedule' flag is flyin'. Just making things smarter, ye see?
  • Simplified Logic fer Discarding Updates: We've also made choosing when to toss out updates less complicated. The 'shouldDiscardUpdate' method's been improved.
  • Remembered the Queue in Batch Updates: The 'resetBatchUpdate' method will now remember where we left off before we reset. No more losing our place in line!
  • Polished the UpdateCharacter Job Framework: The system that sends out jobs fer updating our folks has been cleaned up real good. Now works wonders with folks who've got no updates or old ones. Smooth sailing!
  • Enlarged the Scope o' Test Scenarios: We've put together new test scenarios making sure update orders for characters are dispatched proper-like. This includes first-timers and old-timers, and checks if 'reschedule' flag is handled right. Making sure our ship sails true!

herpaderpaldent and others added 3 commits May 26, 2026 16:51
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
FORK_MEM_PER_PROC=107374182400 (100 GB) makes pokio calculate
maxByMemory=0, resulting in max(1, min(cpuBased, 0))=1 process.
This eliminates the race condition where parallel workers corrupt
.temp/v3.php, causing ParseError on the Formats/ci (push) workflow.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@herpaderpaldent herpaderpaldent merged commit 830ae61 into 4.x May 27, 2026
7 checks passed
@herpaderpaldent herpaderpaldent deleted the feat/reactive-character-scheduling branch May 27, 2026 12:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant