Skip to content

feat(ui): make schedulePublish task queue configurable#16764

Open
ShaunMWallace wants to merge 1 commit into
payloadcms:mainfrom
ShaunMWallace:feat/configurable-schedule-publish-queue
Open

feat(ui): make schedulePublish task queue configurable#16764
ShaunMWallace wants to merge 1 commit into
payloadcms:mainfrom
ShaunMWallace:feat/configurable-schedule-publish-queue

Conversation

@ShaunMWallace
Copy link
Copy Markdown
Contributor

What?

Adds an optional JobsConfig.scheduledPublishQueue?: string config that controls which queue Payload's built-in schedulePublish task is enqueued onto from the admin UI. Default behavior is unchanged — scheduled-publish jobs continue to land on the 'default' queue when this option is not set.

// payload.config.ts
export default buildConfig({
  jobs: {
    tasks: [...],
    scheduledPublishQueue: 'schedule-publish', // ← new, optional
  },
})

Why?

The admin UI's "Schedule Publish" action calls payload.jobs.queue({ task: 'schedulePublish', input, waitUntil }) without a queue argument inside @payloadcms/ui/utilities/schedulePublishHandler.ts. With no consumer-side hook to thread a queue through, the job always lands on 'default'.

Deployments that poll Payload's job runner via Vercel Cron commonly use one cron entry per named queue (?queue=ad-metrics, ?queue=sync, etc.) and never poll 'default'. In that topology, scheduled-publish events stall indefinitely: the "Upcoming Events" row in admin stays forever, the document never publishes, no editor-facing error fires.

I hit this in a production deployment and traced it end-to-end. Downstream fix was a ?queue=default cron entry — that works, but it conflates scheduled-publish with anything else that happens to land on 'default'. A dedicated queue (e.g. 'schedule-publish') is cleaner:

  • Operators can filter by queue in the dashboard for fast scheduled-publish debugging.
  • Limits and processing order can be tuned per-queue.
  • A separate cron runner can carry its own concurrency settings.

How?

Two changes, plus tests:

  1. packages/payload/src/queues/config/types/index.ts — add scheduledPublishQueue?: string to JobsConfig with a doc comment.
  2. packages/ui/src/utilities/schedulePublishHandler.ts — read payload.config.jobs?.scheduledPublishQueue and pass it as queue to payload.jobs.queue(...).

When the field is unset, queue is passed as undefined, and runJobs defaults it to 'default' (packages/payload/src/queues/operations/runJobs/index.ts line ~12: queue = 'default'). Back-compat preserved — no behavior change for any user who doesn't opt in.

Tests

Two new int specs added inside the existing test/versions/int.spec.ts > Scheduled Publish > server functions block:

  • should enqueue scheduled-publish jobs on the configured queue when jobs.scheduledPublishQueue is set — sets the config, calls the handler, asserts the resulting payload-jobs row carries queue: 'schedule-publish'.
  • should fall back to the default queue when jobs.scheduledPublishQueue is not set — deletes the config field, calls the handler, asserts the row carries queue: 'default'.

Both pass locally on sqlite (pnpm test:int:sqlite test/versions/int.spec.ts -t scheduledPublishQueue → 2 passed, 98 skipped). The existing should create using schedule-publish and should delete using schedule-publish tests in the same block continue to pass — no regression.

Build verified: pnpm turbo build --filter 'payload^...' --filter payload --filter @payloadcms/ui (9/9 tasks green).

Notes for reviewers

  • Happy to convert this to a GitHub Discussion if you'd prefer to align on API shape before merging. I went with a global jobs.scheduledPublishQueue because it's the smallest patch surface that fully solves the immediate problem; per-collection (versions.drafts.schedulePublishQueue) could be added additively later if anyone needs to scope by collection.
  • Open to renaming or relocating the field (e.g., under jobs.queues.schedulePublish) if you'd prefer different namespacing.

Fixes #

The admin UI's schedule-publish action enqueues the built-in
`schedulePublish` task without a `queue` arg, falling back to
`'default'`. When a Payload deployment polls only named queues
(e.g. via Vercel Cron entries with `?queue=<name>`), scheduled-publish
events stall indefinitely with no editor-facing signal.

Add `JobsConfig.scheduledPublishQueue?: string` and have
`schedulePublishHandler` read it. Default behavior unchanged
(falls to `'default'` when unset).

Discovered via a Consumer Web prod report; downstream fix
shipped as a default-queue cron, but a dedicated queue is cleaner.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant