Skip to content

Commit 0943bb3

Browse files
authored
fix(selfhost): gate the queue consumer on env readiness at boot (#5050)
Both queue backends self-heal a foreground job left over-deferred across a restart by releasing it and kicking the pump once at boot, inside queue construction/init() itself. That can invoke consume() before `env` is assigned further down in main(), dereferencing undefined and surfacing as a misleading generic job_error right after a container restart. consume() now awaits an envReady promise resolved once env is fully assigned. Closes #5049
1 parent af46a90 commit 0943bb3

1 file changed

Lines changed: 14 additions & 2 deletions

File tree

src/server.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -334,10 +334,21 @@ async function main(): Promise<void> {
334334
/* v8 ignore stop */
335335
const startedAt = Date.now();
336336

337-
// The queue consumer captures `env`, assigned below (the first job only runs once an HTTP/cron event
338-
// arrives, by which point env is set).
337+
// The queue consumer captures `env`, assigned further below once the backend/migrations/AI providers are
338+
// ready. That used to rest on "the first job only runs once an HTTP/cron event arrives, by which point env
339+
// is set" -- false: both queue backends self-heal any foreground job left over-deferred across a restart by
340+
// releasing it and kicking the pump ONCE at boot, inside queue construction/init() itself (see
341+
// releaseStaleForegroundDeferrals in pg-queue.ts/sqlite-queue.ts), which can invoke consume() well before
342+
// `env` below is assigned -- surfacing as a misleading generic job_error ("Cannot read properties of
343+
// undefined") right after a container restart whenever a foreground job happened to be sitting deferred at
344+
// that moment. Gate on envReady so a boot-time release waits for `env` instead of dereferencing it early.
339345
let env: Env;
346+
let markEnvReady!: () => void;
347+
const envReady = new Promise<void>((resolve) => {
348+
markEnvReady = resolve;
349+
});
340350
const consume = async (message: JobMessage): Promise<void> => {
351+
await envReady;
341352
try {
342353
await processJob(env, message);
343354
} catch (error) {
@@ -637,6 +648,7 @@ async function main(): Promise<void> {
637648
return binding ? { REVIEW_AUDIT: binding } : {};
638649
})(),
639650
} as unknown as Env;
651+
markEnvReady();
640652

641653
// GitHub App auth: a successful JWT mint proves GITHUB_APP_PRIVATE_KEY is set and parses as a valid signing
642654
// key. Without this, an invalid/expired key leaves the review pipeline completely dead while /ready still

0 commit comments

Comments
 (0)