mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-12 21:53:00 -06:00
fix(device-pair): keep notifier poll off Gateway startup (#119936)
Punchcard-Session: frost-harbor-willow-ev
This commit is contained in:
@@ -96,12 +96,11 @@ describe("device-pair notify persistence", () => {
|
||||
});
|
||||
}
|
||||
|
||||
it("keeps one notify poll in flight across service recreation", async () => {
|
||||
it("defers the first notify poll and keeps one in flight across service recreation", async () => {
|
||||
vi.useFakeTimers();
|
||||
const firstPoll = createDeferred<Awaited<ReturnType<typeof listDevicePairingMock>>>();
|
||||
const failedPoll = createDeferred<Awaited<ReturnType<typeof listDevicePairingMock>>>();
|
||||
listDevicePairingMock
|
||||
.mockResolvedValueOnce({ pending: [], paired: [] })
|
||||
.mockImplementationOnce(() => firstPoll.promise)
|
||||
.mockImplementationOnce(() => failedPoll.promise)
|
||||
.mockResolvedValue({ pending: [], paired: [] });
|
||||
@@ -109,29 +108,30 @@ describe("device-pair notify persistence", () => {
|
||||
let service = createPairingNotifierService(api);
|
||||
|
||||
await service.start({} as never);
|
||||
expect(listDevicePairingMock).toHaveBeenCalledTimes(1);
|
||||
expect(listDevicePairingMock).not.toHaveBeenCalled();
|
||||
|
||||
await vi.advanceTimersByTimeAsync(10_000);
|
||||
expect(listDevicePairingMock).toHaveBeenCalledTimes(2);
|
||||
expect(listDevicePairingMock).toHaveBeenCalledTimes(1);
|
||||
await vi.advanceTimersByTimeAsync(20_000);
|
||||
expect(listDevicePairingMock).toHaveBeenCalledTimes(2);
|
||||
expect(listDevicePairingMock).toHaveBeenCalledTimes(1);
|
||||
|
||||
await service.stop?.({} as never);
|
||||
service = createPairingNotifierService(createApi());
|
||||
await service.start({} as never);
|
||||
expect(listDevicePairingMock).toHaveBeenCalledTimes(2);
|
||||
await vi.advanceTimersByTimeAsync(10_000);
|
||||
expect(listDevicePairingMock).toHaveBeenCalledTimes(1);
|
||||
|
||||
firstPoll.resolve({ pending: [], paired: [] });
|
||||
await vi.advanceTimersByTimeAsync(0);
|
||||
await vi.advanceTimersByTimeAsync(10_000);
|
||||
expect(listDevicePairingMock).toHaveBeenCalledTimes(3);
|
||||
expect(listDevicePairingMock).toHaveBeenCalledTimes(2);
|
||||
await vi.advanceTimersByTimeAsync(20_000);
|
||||
expect(listDevicePairingMock).toHaveBeenCalledTimes(3);
|
||||
expect(listDevicePairingMock).toHaveBeenCalledTimes(2);
|
||||
|
||||
failedPoll.reject(new Error("poll failed"));
|
||||
await vi.advanceTimersByTimeAsync(0);
|
||||
await vi.advanceTimersByTimeAsync(10_000);
|
||||
expect(listDevicePairingMock).toHaveBeenCalledTimes(4);
|
||||
expect(listDevicePairingMock).toHaveBeenCalledTimes(3);
|
||||
|
||||
await service.stop?.({} as never);
|
||||
});
|
||||
@@ -166,9 +166,7 @@ describe("device-pair notify persistence", () => {
|
||||
},
|
||||
action: "on",
|
||||
});
|
||||
listDevicePairingMock
|
||||
.mockResolvedValueOnce({ pending: [], paired: [] })
|
||||
.mockResolvedValue({ pending: [firstRequest], paired: [] });
|
||||
listDevicePairingMock.mockResolvedValue({ pending: [firstRequest], paired: [] });
|
||||
let service = createPairingNotifierService(api);
|
||||
|
||||
await service.start({} as never);
|
||||
@@ -211,7 +209,7 @@ describe("device-pair notify persistence", () => {
|
||||
ctx: { channel: "telegram", senderId: "old-chat" },
|
||||
action: "on",
|
||||
});
|
||||
listDevicePairingMock.mockResolvedValueOnce({ pending: [], paired: [] }).mockResolvedValue({
|
||||
listDevicePairingMock.mockResolvedValue({
|
||||
pending: [
|
||||
{
|
||||
requestId: "request-1",
|
||||
@@ -261,7 +259,7 @@ describe("device-pair notify persistence", () => {
|
||||
ctx: { channel: "telegram", senderId: "chat-123" },
|
||||
action: "once",
|
||||
});
|
||||
listDevicePairingMock.mockResolvedValueOnce({ pending: [], paired: [] }).mockResolvedValue({
|
||||
listDevicePairingMock.mockResolvedValue({
|
||||
pending: [
|
||||
{
|
||||
requestId: "request-1",
|
||||
@@ -325,6 +323,7 @@ describe("device-pair notify persistence", () => {
|
||||
const service = createPairingNotifierService(api);
|
||||
|
||||
await service.start({} as never);
|
||||
await vi.advanceTimersByTimeAsync(10_000);
|
||||
|
||||
expect(sendText).not.toHaveBeenCalled();
|
||||
await expect(
|
||||
@@ -367,6 +366,7 @@ describe("device-pair notify persistence", () => {
|
||||
});
|
||||
const service = createPairingNotifierService(api);
|
||||
await service.start({} as never);
|
||||
await vi.advanceTimersByTimeAsync(10_000);
|
||||
|
||||
expect(sendText).toHaveBeenCalledWith(
|
||||
expect.objectContaining({ text: expect.stringContaining("ID: request-same-ms") }),
|
||||
@@ -404,6 +404,7 @@ describe("device-pair notify persistence", () => {
|
||||
const service = createPairingNotifierService(api);
|
||||
|
||||
await service.start({} as never);
|
||||
await vi.advanceTimersByTimeAsync(10_000);
|
||||
|
||||
expect(sendText).toHaveBeenCalledTimes(1);
|
||||
expect(sendText).toHaveBeenCalledWith(
|
||||
|
||||
@@ -454,14 +454,13 @@ export function createPairingNotifierService(api: OpenClawPluginApi): OpenClawPl
|
||||
|
||||
return {
|
||||
id: "device-pair-notifier",
|
||||
start: async () => {
|
||||
start: () => {
|
||||
const tick = async () => {
|
||||
await runNotifyPoll(api);
|
||||
};
|
||||
|
||||
await tick().catch((err: unknown) => {
|
||||
api.logger.warn(`device-pair: initial notify poll failed: ${formatErrorMessage(err)}`);
|
||||
});
|
||||
// Pairing notifications are eventual background work. Starting on the
|
||||
// existing interval keeps SQLite pairing scans out of Gateway readiness.
|
||||
notifyInterval = setInterval(() => {
|
||||
tick().catch((err: unknown) => {
|
||||
api.logger.warn(`device-pair: notify poll failed: ${formatErrorMessage(err)}`);
|
||||
|
||||
Reference in New Issue
Block a user