mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-23 07:51:33 +00:00
fix(runtime): duplicate messages, share singleton state across bundled chunks (#43683)
* Tests: add fresh module import helper * Process: share command queue runtime state * Agents: share embedded run runtime state * Reply: share followup queue runtime state * Reply: share followup drain callback state * Reply: share queued message dedupe state * Reply: share inbound dedupe state * Tests: cover shared command queue runtime state * Tests: cover shared embedded run runtime state * Tests: cover shared followup queue runtime state * Tests: cover shared inbound dedupe state * Tests: cover shared Slack thread participation state * Slack: share sent thread participation state * Tests: document fresh import helper * Telegram: share draft stream runtime state * Tests: cover shared Telegram draft stream state * Telegram: share sent message cache state * Tests: cover shared Telegram sent message cache * Telegram: share thread binding runtime state * Tests: cover shared Telegram thread binding state * Tests: avoid duplicate shared queue reset * refactor(runtime): centralize global singleton access * refactor(runtime): preserve undefined global singleton values * test(runtime): cover undefined global singleton values --------- Co-authored-by: Nimrod Gutman <nimrod.gutman@gmail.com>
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { importFreshModule } from "../../test/helpers/import-fresh.js";
|
||||
|
||||
const diagnosticMocks = vi.hoisted(() => ({
|
||||
logLaneEnqueue: vi.fn(),
|
||||
@@ -334,4 +335,42 @@ describe("command queue", () => {
|
||||
resetAllLanes();
|
||||
await expect(enqueueCommand(async () => "ok")).resolves.toBe("ok");
|
||||
});
|
||||
|
||||
it("shares lane state across distinct module instances", async () => {
|
||||
const commandQueueA = await importFreshModule<typeof import("./command-queue.js")>(
|
||||
import.meta.url,
|
||||
"./command-queue.js?scope=shared-a",
|
||||
);
|
||||
const commandQueueB = await importFreshModule<typeof import("./command-queue.js")>(
|
||||
import.meta.url,
|
||||
"./command-queue.js?scope=shared-b",
|
||||
);
|
||||
const lane = `shared-state-${Date.now()}-${Math.random().toString(16).slice(2)}`;
|
||||
|
||||
let release!: () => void;
|
||||
const blocker = new Promise<void>((resolve) => {
|
||||
release = resolve;
|
||||
});
|
||||
|
||||
commandQueueA.resetAllLanes();
|
||||
|
||||
try {
|
||||
const task = commandQueueA.enqueueCommandInLane(lane, async () => {
|
||||
await blocker;
|
||||
return "done";
|
||||
});
|
||||
|
||||
await vi.waitFor(() => {
|
||||
expect(commandQueueB.getQueueSize(lane)).toBe(1);
|
||||
expect(commandQueueB.getActiveTaskCount()).toBe(1);
|
||||
});
|
||||
|
||||
release();
|
||||
await expect(task).resolves.toBe("done");
|
||||
expect(commandQueueB.getQueueSize(lane)).toBe(0);
|
||||
} finally {
|
||||
release();
|
||||
commandQueueA.resetAllLanes();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user