Skip to content

Reece/queue library - #222

Draft
reeceyang wants to merge 7 commits into
ian/use-commit-tsfrom
reece/queue-library
Draft

reeceyang wants to merge 7 commits into
ian/use-commit-tsfrom
reece/queue-library

Conversation

@reeceyang

Copy link
Copy Markdown
Contributor

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

ianmacartney and others added 7 commits August 3, 2026 17:42
`v.commitTs()` and `db.vars.commitTs` landed in convex 1.43, and the pending
queues are about to be ordered by them, so raise the peer dependency to match.

Also bumps convex-test to 0.0.55-alpha.0, the first version that resolves the
commitTs placeholder at commit time instead of storing it verbatim.
The `segment` fields on pendingStart/pendingCompletion/pendingCancelation held
a 100ms bucket derived from `Date.now()`. That is read when a mutation *starts*,
so a slow transaction could commit an entry behind a cursor the main loop had
already read past. 0.4.7 compensated by rewinding each cursor 15 seconds on
every scan and rescanning each table from the beginning once a minute, which at
load meant re-reading thousands of tombstones per iteration.

Those fields are now `v.commitTs()`, written as `db.vars.commitTs` and resolved
at commit, so an entry cannot appear behind a timestamp already read. The rewind
buffer and the periodic rescan are gone; the recovery iteration still runs, but
only to find stuck running jobs. On a 5000-task saturation benchmark
(parallelism 200, 20ms tasks) throughput went from 121 to 144 tasks/s and p99
latency from ~32s to ~25s.

The field and index keep their names so existing documents still validate. The
values are now nanoseconds rather than 100ms buckets; an older version's much
smaller ones sort first and get processed promptly on upgrade.

Work that shouldn't start yet stores its start time in the same field, which
sorts after everything committed before then, so one index covers both cases:

- A retry backoff is written directly, however short. `rescheduleJob` runs
  inside the transaction that writes the cursor, so a time past now is certain
  to sort ahead of it.
- A caller's `runAt` is written directly only when it is more than
  SAFE_FUTURE_MS out, far enough that no commit latency could place it in the
  past. Nearer than that it is ordered by the commit timestamp with `runAt`
  stored alongside, and the loop moves it forward itself (`promoteScheduled`)
  rather than starting it.

Eligibility is bounded by `endOfMs(now)` rather than `toTimestamp(now)`:
`Date.now()` is whole milliseconds but a commit timestamp is not, so a bound at
the start of the current millisecond would skip everything that just committed.

Two paths that returned without deleting a pendingStart — work already in
`running`, and a cancelation whose work document is gone — now delete it. They
used to be repaired by the periodic rescan; with the cursor no longer rewinding,
an entry left behind would never be read again.
The throughput scenarios only ever enqueue work that is ready immediately, so
nothing exercised the two paths that write a wall-clock time into the ordering
field instead of the commit-timestamp placeholder. Those are also the paths
convex-test could be lenient about, since it does not enforce what the backend
accepts for a `v.commitTs()` field.

`test/scheduling:default` enqueues one delayed mutation and one action that
fails twice, then reports when each ran. Against the dev deployment: a
`runAfter: 8000` ran 59ms after its runAt and never early, retries backed off
722ms then 939ms over 3 attempts, and a `runAfter: 360000` was stored at its
start time with no promotion pass and ran 196ms late.
Notes the new ordering, the benchmark result, what happens to entries an older
version wrote, and the convex 1.43 requirement.
@pkg-pr-new

pkg-pr-new Bot commented Aug 5, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/get-convex/workpool/@convex-dev/workpool@222

commit: 9df96a5

@reeceyang
reeceyang changed the base branch from main to ian/use-commit-ts August 5, 2026 00:50
@ianmacartney
ianmacartney force-pushed the ian/use-commit-ts branch 5 times, most recently from ba7eb18 to 98666b0 Compare September 15, 2026 23:31
@ianmacartney
ianmacartney force-pushed the ian/use-commit-ts branch 2 times, most recently from 65c31bd to 65184eb Compare October 10, 2026 01:35
@ianmacartney
ianmacartney force-pushed the ian/use-commit-ts branch 5 times, most recently from fb5a6d9 to 68a0983 Compare October 28, 2026 22:29
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.

2 participants