feat(workflow): delay action with deferred job queue#35
Open
mpge wants to merge 3 commits intofeat/workflow-executorfrom
Open
feat(workflow): delay action with deferred job queue#35mpge wants to merge 3 commits intofeat/workflow-executorfrom
mpge wants to merge 3 commits intofeat/workflow-executorfrom
Conversation
Splits workflow execution around a `delay N` step: actions before the delay run inline, remaining actions are persisted as a `escalated_deferred_workflow_jobs` row with run_at = now + N seconds. A WP-Cron job on the shared `escalated_every_minute` interval picks up due pending jobs, re-invokes the executor with the stored remaining_actions JSON, and flips the row to `done` / `failed` (retained for audit, composite `(status, run_at)` index for efficient polling). What's added: - `Models\DeferredWorkflowJob` — find/create/update/pending helpers - `Cron\Deferred_Workflow_Jobs_Check` registered on `escalated_run_due_deferred_workflow_jobs` hook - Activator: new table creation + cron event scheduling - Bootstrap: registers the new cron handler alongside Snooze_Check - Executor: detects `delay`, serializes remaining actions, persists the job, short-circuits the rest of the run - Executor: `run_due_deferred_jobs()` sweeps pending rows - 5 new PHPUnit cases: delay pauses + persists, invalid value skips cleanly, resumer marks done, resumer marks failed when ticket deleted, resumer skips rows not yet due Mirrors the NestJS reference impl in escalated-nestjs/src/services/workflow-executor.service.ts and the Spring port in escalated-spring PR #35. Stacked on feat/workflow-executor. Upgrade note: existing installs need to reactivate the plugin to pick up the new table. New installs get it automatically on first activate.
run_at is written via gmdate() (UTC). pending() was reading via
current_time('mysql') which returns the WP-configured timezone —
on non-UTC sites, due jobs could be picked up early or late by up to
the timezone offset. Switch to current_time('mysql', true) to force
GMT on read, matching the write path.
created_at/updated_at stay on current_time('mysql') to match the rest
of the plugin's models (Reply, Tag, etc.) — those are audit-display
fields, not load-bearing for logic.
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.
Summary
Adds the `delay` workflow action to WordPress as the ninth entry in the catalog. Splits execution around a wait clause: actions before the delay run inline, remaining actions are persisted as an `escalated_deferred_workflow_jobs` row with `run_at = now + N seconds`. A WP-Cron handler running on the shared `escalated_every_minute` interval picks up due pending jobs, re-invokes the executor with the stored JSON, and flips the row to `done` / `failed` (retained for audit).
What's added
Upgrade note
Existing installs need to reactivate the plugin to pick up the new table (via `deactivate → activate`). New installs get it automatically. This is a pre-existing infrastructure gap unrelated to this PR — a proper `plugins_loaded` version-check migration path is a separate future concern.
Base / Stacking
Stacked on `feat/workflow-executor` (PR #28). CI won't exercise this branch until that base merges and this rebases onto `main`.
Test plan