docs: fence worker_functions row before deprecating workers in update guide - #670
Conversation
… guide The production Update Deployed Flows guide told operators to deprecate old workers, deploy, and wait for cron. While the pgflow.worker_functions row stays enabled, the ensure_workers() cron (1s interval) can start another instance of the old deployed function between deprecation and deployment, because deprecated workers do not count as alive for the restart check. Rewrite the guide around a disable fence for one worker function: - record the current enabled value, then set enabled = false - deprecate its live pgflow.workers rows - verify polling stopped (heartbeat window) and in-flight work drained (step_tasks.status leaves 'started' for the deprecated workers) - deploy the replacement while the row stays disabled - restore the exact recorded enabled value, not an inferred one - confirm the replacement worker reports a current heartbeat Add failure guidance covering a worker that does not drain or does not restart, with inspection SQL (worker listing, stuck task detail, last_invoked_at, cron.job entry). Link the corrected sequence from the Worker Deprecation section of the Worker Management guide. Per-step, alias-version, and shared-queue rollout instructions stay with issues #651, #648, and #652; deliberately not documented here. Closes #654
|
|
View your CI Pipeline Execution ↗ for commit a1e54bd
💡 Verify your cache is correct by running tasks in a sandbox. Read docs ↗ ☁️ Nx Cloud last updated this comment at |
| ```sql "true" | ||
| UPDATE pgflow.worker_functions | ||
| SET enabled = true | ||
| WHERE function_name = 'your-worker-name'; | ||
| ``` |
There was a problem hiding this comment.
The SQL example hardcodes enabled = true, but step 1 (line 35) instructs users to record and restore the exact original value, "even if it is false". Users who copy-paste this SQL will incorrectly enable an intentionally disabled function.
UPDATE pgflow.worker_functions
SET enabled = <recorded-value-from-step-1>
WHERE function_name = 'your-worker-name';The example should use a placeholder like <recorded-value-from-step-1> or provide both cases explicitly, since this defeats the purpose of recording the value in step 1.
| ```sql "true" | |
| UPDATE pgflow.worker_functions | |
| SET enabled = true | |
| WHERE function_name = 'your-worker-name'; | |
| ``` | |
| ```sql "<recorded-value-from-step-1>" | |
| UPDATE pgflow.worker_functions | |
| SET enabled = <recorded-value-from-step-1> | |
| WHERE function_name = 'your-worker-name'; |
*Spotted by [Graphite](https://app.graphite.com/diamond/?org=pgflow-dev&ref=ai-review-comment)*<i class='graphite__hidden'><br /><br /><a href="https://app.graphite.com/github/pr/pgflow-dev/pgflow/670?chatWithGeneratedComment=ff8839d3-5940-4fe7-a2da-246ca18f8fd7"><picture><source media="(prefers-color-scheme: dark)" srcset="https://static.graphite.dev/github-diamond-fix-in-graphite-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://static.graphite.dev/github-diamond-fix-in-graphite-light.svg"><img alt="Fix in Graphite" src="https://static.graphite.dev/github-diamond-fix-in-graphite-dark.svg"></picture></a></i><i class='graphite__hidden'><br /><br />Is this helpful? React 👍 or 👎 to let us know.</i>
🔍 Preview Deployment: Website✅ Deployment successful! 🔗 Preview URL: https://pr-670.pgflow.pages.dev 📝 Details:
_Last updated: _ |
jumski
left a comment
There was a problem hiding this comment.
all good - merge this pr using gt if it checks are green, then remove the current worktree and then close this issue workspace
| --- | ||
| title: Update Deployed Flows | ||
| description: Safe workflow for deploying flow updates to production using worker deprecation | ||
| description: Disable restarts, deprecate workers, drain, deploy, then re-enable to update deployed flows safely |
There was a problem hiding this comment.
this is user facing description - do you think its better now?
🚀 Production Deployment: Website✅ Successfully deployed to production! 🔗 Production URL: https://pgflow.dev 📝 Details:
Deployed at: 2026-09-04T22:55:22+02:00 |
Summary
pgflow.worker_functions.enabledvalue, disable the row, deprecate its live workers, verify polling and in-flight work drained, deploy the replacement while the row stays disabled, restore the exact recorded value, and confirm the replacement worker reports a current heartbeat.Every step ships copyable SQL: record enabled state, disable the function, deprecate workers, drain checks (heartbeat window +
step_tasksleavingstarted), restore recorded state, replacement worker and heartbeat check.Rationale: while the
worker_functionsrow stays enabled, theensure_workers()cron (1s interval) can start another instance of the old deployed function between deprecation and deployment, because deprecated workers do not count as alive for the restart check.Per-step, alias-version, and shared-queue rollout instructions remain with #651, #648, and #652.
Checks
pnpm --filter @pgflow/website buildpasses (astro check clean, 135 pages, all internal links valid).pkgs/core/schemas/(worker_functions, workers, ensure_workers, step_tasks) and worker runtime code.Closes #654