Repository navigation
Conversation
This branch has not been deployed
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.
conductor.getExecution()could not tell a sleeping or suspended execution from one waiting for its first attempt: all of them werepending. Operators also had no cheap way to see the depth of each queue.Waiting status
getExecution(and the polling inconductor.waitForResult) reports a newwaitingstatus with awaitingForreason. It is derived from existing columns:child:waiting_on_execution_idis set.wait:waiting_step_keyis set and there is no child.run_atis still in the future. Once a deadline passes, the execution ispendinguntil it is claimed.pending.Sleep detection
A sleep step used to store
null, which made a sleep in progress look the same as a retry that failed right after the sleep woke up. Settlement now stores the sleep's wake-up time in the same step insert ({until}) instead ofnull. An execution counts as sleeping only while itsrun_atequals that value, so a retry, window release or re-invoke that movesrun_atends the sleep. There are no new writes or columns; the existing insert just stores a different value.pgconductor.queue_statsA view with one row per queue:
ready,oldest_ready_age,running,suspended(sleeping, waiting, backing off or delayed) andfailed_last_hour(excluding cancellations). It is documented on a new Operations › Monitoring page.Each count reads one existing partial index (
is_available, active concurrency,failed_at), so the cost grows with unfinished executions and the last hour's failures, not with history. Two planner details matter:_private_current_time()runs once per row inside the aggregate filters.failed_atis compared against a scalar subquery and a two-sided range. That keeps it an index condition with a good row estimate, so the plan stays underjit_above_cost. A per-queue lateral version cost about 45 ms of JIT compilation per call.EXPLAIN on Postgres 15 with 995k executions (900k completed, 45k failed with 5k in the last hour, 40k ready, 9k suspended, 1k running) takes about 25 ms warm:
EXPLAIN (ANALYZE, BUFFERS)
Verification
execution-waiting-status.test.tscover sleep, child with and without a timeout, event, signal, the return topendingafter a sleep elapses, retries (including a failure right after a sleep), delayed starts, andwaitForResulton a waiting execution. All 7 failed againstmain.queue-stats.test.tscovers the view under a fake clock.just lint,just formatandpnpm typecheckpass. In the fullpnpm testrun, 622/623 tests passed. The one failure waswait-deadlines.test.ts› "waitForAny with an event and a completion settled after the deadline › times out", which passed 3/3 when run alone. It looks like a timing flake under the full parallel load: fake time keeps running and its deadline is 1 s.Follow-ups
wait-deadlinestest fails again in CI, it needs a wider deadline margin.