mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-04 16:51:36 +00:00
fix(nostr): normal shutdown no longer reports relay errors (#111905)
This commit is contained in:
@@ -6,25 +6,36 @@ type RelayHandlers = Parameters<SimplePool["subscribeMany"]>[2];
|
||||
|
||||
function createHarness() {
|
||||
const handlers: RelayHandlers[] = [];
|
||||
const abortController = new AbortController();
|
||||
const subscribeMany = vi.fn(
|
||||
(_relays: string[], _filter: unknown, nextHandlers: RelayHandlers) => {
|
||||
handlers.push(nextHandlers);
|
||||
return { close: vi.fn() };
|
||||
nextHandlers.abort?.addEventListener(
|
||||
"abort",
|
||||
() => nextHandlers.onclose?.([String(nextHandlers.abort?.reason ?? "aborted")]),
|
||||
{ once: true },
|
||||
);
|
||||
return {
|
||||
close: vi.fn(async (reason?: string) => {
|
||||
nextHandlers.onclose?.([reason ?? "closed by caller"]);
|
||||
}),
|
||||
};
|
||||
},
|
||||
);
|
||||
const onBackfillComplete = vi.fn<(relays: string[]) => void>();
|
||||
const onClose = vi.fn<(relay: string, reasons: string[]) => void>();
|
||||
const group = createNostrRelaySubscriptionGroup({
|
||||
pool: { subscribeMany } as unknown as SimplePool,
|
||||
relays: ["wss://one.example", "wss://two.example"],
|
||||
filter: { kinds: [4] },
|
||||
abort: new AbortController().signal,
|
||||
abort: abortController.signal,
|
||||
onEvent: (_event: Event) => {},
|
||||
onBackfillComplete,
|
||||
onClose: () => {},
|
||||
onClose,
|
||||
eoseConfirmDeadlineMs: 10,
|
||||
});
|
||||
group.start();
|
||||
return { group, handlers, onBackfillComplete, subscribeMany };
|
||||
return { abortController, group, handlers, onBackfillComplete, onClose, subscribeMany };
|
||||
}
|
||||
|
||||
describe("Nostr relay subscriptions", () => {
|
||||
@@ -66,4 +77,22 @@ describe("Nostr relay subscriptions", () => {
|
||||
expect(onBackfillComplete).not.toHaveBeenCalled();
|
||||
await group.close("test complete");
|
||||
});
|
||||
|
||||
it("does not report locally requested closes as relay failures", async () => {
|
||||
const { abortController, group, onClose } = createHarness();
|
||||
|
||||
abortController.abort("closed by caller");
|
||||
await group.close("closed by caller");
|
||||
|
||||
expect(onClose).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("still reports closes initiated by the relay", async () => {
|
||||
const { group, handlers, onClose } = createHarness();
|
||||
|
||||
handlers[0]?.onclose?.(["relay unavailable"]);
|
||||
|
||||
expect(onClose).toHaveBeenCalledWith("wss://one.example", ["relay unavailable"]);
|
||||
await group.close("test complete");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -18,6 +18,7 @@ export function createNostrRelaySubscriptionGroup(options: {
|
||||
const relays = [...new Set(options.relays)];
|
||||
const subscriptions: Array<ReturnType<SimplePool["subscribeMany"]>> = [];
|
||||
const deadlineTimers = new Set<ReturnType<typeof setTimeout>>();
|
||||
let locallyClosing = false;
|
||||
const backfillStatus = new Map<string, BackfillStatus>(
|
||||
relays.map((relay): [string, BackfillStatus] => [relay, "pending"]),
|
||||
);
|
||||
@@ -74,7 +75,9 @@ export function createNostrRelaySubscriptionGroup(options: {
|
||||
clearTimeout(deadlineTimer);
|
||||
deadlineTimers.delete(deadlineTimer);
|
||||
settleBackfill(relay, "incomplete");
|
||||
options.onClose(relay, reasons);
|
||||
if (!locallyClosing && !options.abort.aborted) {
|
||||
options.onClose(relay, reasons);
|
||||
}
|
||||
},
|
||||
// Own earlier deadline marks synthetic library EOSE as incomplete.
|
||||
maxWait: confirmDeadlineMs + LIBRARY_EOSE_TIMEOUT_MARGIN_MS,
|
||||
@@ -84,6 +87,8 @@ export function createNostrRelaySubscriptionGroup(options: {
|
||||
}
|
||||
},
|
||||
close: async (reason: string): Promise<void> => {
|
||||
// nostr-tools reports caller-requested closes through the same callback as relay failures.
|
||||
locallyClosing = true;
|
||||
clearDeadlines();
|
||||
await Promise.all(subscriptions.map(async (subscription) => subscription.close(reason)));
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user