From 7391737617fdbb43654209b3eb620df05505ec3d Mon Sep 17 00:00:00 2001 From: Brandur Date: Tue, 6 Oct 2026 12:45:31 -0500 Subject: [PATCH] Fix another intermittently failing JavaScript test case Just another commonly failing test as observed places like [1]. The test case expected a 5 ms timer to fire at least three times within 50 ms, but under CI load, this might happen only twice. It's been fixed to explicit await three background insertions. [1] https://github.com/riverqueue/river/actions/runs/37504874545/job/112410850148?pr=1459 --- js/driver/sqlite/src/scope.test.ts | 36 ++++++++++++------------------ 1 file changed, 14 insertions(+), 22 deletions(-) diff --git a/js/driver/sqlite/src/scope.test.ts b/js/driver/sqlite/src/scope.test.ts index 306ba55ab..680d3da18 100644 --- a/js/driver/sqlite/src/scope.test.ts +++ b/js/driver/sqlite/src/scope.test.ts @@ -1,4 +1,3 @@ -import { EventEmitter } from "node:events"; import { mkdtempSync, rmSync } from "node:fs"; import { readFile, stat } from "node:fs/promises"; import { tmpdir } from "node:os"; @@ -149,38 +148,31 @@ describe("SqliteDriver insertion transactions", () => { }); test("lets unrelated work that inherited its async context run before the write", async () => { - // A shared batcher created lazily inside insert middleware inherits the - // insertion's async context, so its later flushes run "inside" River's - // transaction while the middleware still awaits I/O before next(). - const bus = new EventEmitter(); - let batcher: NodeJS.Timeout | undefined; - onTestFinished(() => clearInterval(batcher)); + // Callbacks created inside middleware inherit its transaction context. + // Run three background flushes while middleware waits before next(), + // awaiting each insertion instead of relying on a fixed time window. const { client, count } = await setup({ insertMiddleware: [ async (context, next) => { - if ( - batcher === undefined && - context.requests[0]?.args.wire === true - ) { - batcher = setInterval(() => bus.emit("flush"), 5); - await new Promise((resolve) => setTimeout(resolve, 50)); + if (context.requests[0]?.args.wire === true) { + for (let index = 0; index < 3; index++) { + const flushed = Promise.withResolvers(); + setImmediate(() => { + void client + .insert(scopedJob, {}) + .then(flushed.resolve, flushed.reject); + }); + await flushed.promise; + } } return next(); }, ], }); - const flushed: Promise[] = []; - bus.on("flush", () => { - flushed.push(client.insert(scopedJob, {})); - }); await client.insert(scopedJob, { wire: true }); - clearInterval(batcher); - const results = await Promise.allSettled(flushed); - expect(results.length).toBeGreaterThan(2); - expect(results.filter(({ status }) => status === "rejected")).toEqual([]); - expect(count("river_job")).toBe(results.length + 1); + expect(count("river_job")).toBe(4); }); test("lets middleware and beforeInsert hooks call River before the write", async () => {