Skip to content

Commit c8872e2

Browse files
committed
test(run-engine): pin the snapshotRoute the vtime TTL sweep hands the worker
The fix for the missing snapshotRoute shipped without a test, on a field that had already regressed twice. Reverting those lines left the suite green: every other assertion about that sweep is about ckIndex and ckVtime bookkeeping, and none of them read back the item the worker actually receives. This enqueues a run carrying a route, runs the sweep, and reads the serialised item out of the worker hash. Verified in both directions: dropping the field from the item fails it with `expected undefined to deeply equal { kind: 's2', version: 3 }`.
1 parent c5c6bc9 commit c8872e2

1 file changed

Lines changed: 50 additions & 0 deletions

File tree

‎internal-packages/run-engine/src/run-queue/tests/ckVtime.test.ts‎

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1660,6 +1660,56 @@ describe("CK virtual-time (SFQ) dequeue", () => {
16601660
}
16611661
});
16621662

1663+
redisTest("TTL expiry hands the worker the run's snapshotRoute", async ({ redisContainer }) => {
1664+
// The sweep reads the message before deleting it so the worker can resolve residency from
1665+
// the route the run was born with. The vtime build lost that read for a while, because it
1666+
// was a copy taken before the route existed, and nothing here noticed: every other
1667+
// assertion in this file is about ckIndex and ckVtime bookkeeping.
1668+
const queue = createQueue(redisContainer);
1669+
try {
1670+
const route = { kind: "s2", version: 3 };
1671+
await queue.enqueueMessage({
1672+
env: authenticatedEnvDev,
1673+
message: makeMessage({
1674+
runId: "r-route",
1675+
concurrencyKey: "route",
1676+
timestamp: Date.now() - 100_000,
1677+
snapshotRoute: route,
1678+
}),
1679+
workerQueue: authenticatedEnvDev.id,
1680+
skipDequeueProcessing: true,
1681+
});
1682+
1683+
const v = variantName("route");
1684+
const shard = testOptions.keys.masterQueueShardForEnvironment(authenticatedEnvDev.id, 2);
1685+
const ttlQueueKey = testOptions.keys.ttlQueueKeyForShard(shard);
1686+
await queue.redis.zadd(
1687+
ttlQueueKey,
1688+
Date.now() - 1000,
1689+
`${v}|r-route|${authenticatedEnvDev.organization.id}`
1690+
);
1691+
1692+
await queue.redis.expireTtlRunsVtimeTracked(
1693+
ttlQueueKey,
1694+
"runqueue:test:",
1695+
Date.now().toString(),
1696+
"10",
1697+
"2",
1698+
"ttlworker",
1699+
// The script uses this verbatim, so prefix it here to match what ioredis prefixes on read.
1700+
"runqueue:test:ttlworkeritems",
1701+
"30000",
1702+
"86400"
1703+
);
1704+
1705+
const serialized = await queue.redis.hget("ttlworkeritems", "r-route");
1706+
expect(serialized).not.toBeNull();
1707+
expect(JSON.parse(serialized!).item.snapshotRoute).toEqual(route);
1708+
} finally {
1709+
await queue.quit();
1710+
}
1711+
});
1712+
16631713
redisTest(
16641714
"flag off creates no vtime keys and matches head-timestamp order",
16651715
async ({ redisContainer }) => {

0 commit comments

Comments
 (0)