From 2c4bceb7680b04e3af92d6c588f0b65e51dc788a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Lohrer?= Date: Tue, 28 Apr 2026 08:27:12 +0200 Subject: [PATCH] fix(snapshot): cache akkumuliert deletedCoords + timeout-kommentar MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Code-review-feedback aus etappe 2.9/2.10: 1. cli.ts: deletedCoords im cache wird ab jetzt akkumuliert statt ersetzt. Vorher wurden bei einem run nur die aktuell von relays gelieferten kind:5-coords geschrieben — wenn ein relay beim naechsten run die alten deletions nicht mehr liefert (GC, relay-tausch), waere die geschichte verloren und newDeletionsCount im naechsten lauf wieder "neu" -> false-positive hard-fail im drop-check. 2. relays.ts: kommentar zum belt-and-suspenders-setTimeout neben dem RxJS-timeout-operator, damit der zweck (handle-cleanup falls beide subscribe-callbacks verschluckt werden) klar ist. Co-Authored-By: Claude Opus 4.7 (1M context) --- snapshot/src/cli.ts | 9 +++++++-- snapshot/src/core/relays.ts | 5 +++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/snapshot/src/cli.ts b/snapshot/src/cli.ts index b44b346..dbd629e 100644 --- a/snapshot/src/cli.ts +++ b/snapshot/src/cli.ts @@ -92,12 +92,17 @@ async function main(): Promise { posts: postJsons, }) - const allDeletedCoords = deletions.flatMap((d) => + const currentDeletedCoords = deletions.flatMap((d) => d.tags.filter((t) => t[0] === 'a' && t[1]).map((t) => t[1] as string) ) + // Cache akkumuliert deletedCoords ueber alle bisherigen runs — nicht + // ersetzen: wenn ein relay beim naechsten run die alten kind:5-events + // nicht mehr liefert (GC, relay-tausch), wuerde sonst der vergleich + // gegen previousDeletedCoords im naechsten lauf wieder als "neu" + // werten und einen false-positive hard-fail ausloesen. const newCache: CacheState = { lastKnownGoodCount: filtered.length, - deletedCoords: [...new Set(allDeletedCoords)], + deletedCoords: [...new Set([...(cache?.deletedCoords ?? []), ...currentDeletedCoords])], } await writeCache(cachePath, newCache) diff --git a/snapshot/src/core/relays.ts b/snapshot/src/core/relays.ts index 348010d..7510690 100644 --- a/snapshot/src/core/relays.ts +++ b/snapshot/src/core/relays.ts @@ -70,6 +70,11 @@ export const defaultEventFetcher: EventFetcher = async (relay, pubkey) => { error: () => resolve(out), complete: () => resolve(out), }) + // Belt-and-suspenders: falls subscribe-callback weder error noch + // complete feuert (z.B. timeout-operator wird intern verschluckt), + // schliessen wir nach timeout+1s manuell. Resolve() kommt dann nicht + // mehr durch (Promise schon settled), aber der Relay-Handle wird + // entsorgt — kein leak. setTimeout(() => sub.unsubscribe(), 11_000) }) }