diff --git a/packages/app/src/Element/SubDebug.tsx b/packages/app/src/Element/SubDebug.tsx index 5ce1d17f..73375741 100644 --- a/packages/app/src/Element/SubDebug.tsx +++ b/packages/app/src/Element/SubDebug.tsx @@ -30,10 +30,10 @@ function Queries() { return total; } - function queryInfo(q: { id: string; filters: Array; closing: boolean; subFilters: Array }) { + function queryInfo(q: { id: string; filters: Array; subFilters: Array }) { return (
- {q.closing ? {q.id} : <>{q.id}} + {q.id}
copy(JSON.stringify(q.filters))} className="pointer">   Filters: {q.filters.length} ({countElements(q.filters)} elements) diff --git a/packages/app/src/Hooks/useRequestBuilder.tsx b/packages/app/src/Hooks/useRequestBuilder.tsx index 04923ed3..6d2fb8a7 100644 --- a/packages/app/src/Hooks/useRequestBuilder.tsx +++ b/packages/app/src/Hooks/useRequestBuilder.tsx @@ -12,6 +12,7 @@ const useRequestBuilder = (type, rb); const release = q.feed.hook(onChanged); + q.uncancel(); return () => { q.cancel(); release(); diff --git a/packages/app/src/System/NostrSystem.ts b/packages/app/src/System/NostrSystem.ts index 925fc35e..a34a641f 100644 --- a/packages/app/src/System/NostrSystem.ts +++ b/packages/app/src/System/NostrSystem.ts @@ -122,7 +122,9 @@ export class NostrSystem extends ExternalStore implements System Query(type: { new (): T }, req: RequestBuilder): Query { const existing = this.Queries.get(req.id); if (existing) { - const filters = req.buildDiff(this.#relayCache, existing.filters); + const filters = !req.options?.skipDiff + ? req.buildDiff(this.#relayCache, existing.filters) + : req.build(this.#relayCache); if (filters.length === 0 && !!req.options?.skipDiff) { return existing; } else { @@ -138,11 +140,7 @@ export class NostrSystem extends ExternalStore implements System const store = new type(); const filters = req.build(this.#relayCache); - const q = new Query(req.id, store); - if (req.options?.leaveOpen) { - q.leaveOpen = req.options.leaveOpen; - } - + const q = new Query(req.id, store, req.options?.leaveOpen); this.Queries.set(req.id, q); for (const subQ of filters) { this.SendQuery(q, subQ).then(qta => @@ -222,7 +220,6 @@ export class NostrSystem extends ExternalStore implements System return { id: a.id, filters: a.filters, - closing: a.closing, subFilters: [], }; }), @@ -230,12 +227,12 @@ export class NostrSystem extends ExternalStore implements System } #cleanup() { - const now = unixNowMs(); let changed = false; for (const [k, v] of this.Queries) { - if (v.closingAt && v.closingAt < now) { + if (v.canRemove()) { v.sendClose(); this.Queries.delete(k); + this.#log("Deleted query %s", k); changed = true; } } diff --git a/packages/app/src/System/Query.ts b/packages/app/src/System/Query.ts index b6e14700..581d37f1 100644 --- a/packages/app/src/System/Query.ts +++ b/packages/app/src/System/Query.ts @@ -120,12 +120,12 @@ export class Query implements QueryBase { /** * Leave the query open until its removed */ - leaveOpen = false; + #leaveOpen = false; /** * Time when this query can be removed */ - #cancelTimeout?: number; + #cancelAt?: number; /** * Timer used to track tracing status @@ -140,18 +140,15 @@ export class Query implements QueryBase { #log = debug("Query"); #allFilters: Array = []; - constructor(id: string, feed: NoteStore) { + constructor(id: string, feed: NoteStore, leaveOpen?: boolean) { this.id = id; this.#feed = feed; + this.#leaveOpen = leaveOpen ?? false; this.#checkTraces(); } - get closing() { - return this.#cancelTimeout !== undefined; - } - - get closingAt() { - return this.#cancelTimeout; + canRemove() { + return this.#cancelAt !== undefined && this.#cancelAt < unixNowMs(); } /** @@ -174,8 +171,15 @@ export class Query implements QueryBase { } } + /** + * This function should be called when this Query object and FeedStore is no longer needed + */ cancel() { - this.#cancelTimeout = unixNowMs() + 5_000; + this.#cancelAt = unixNowMs() + 5_000; + } + + uncancel() { + this.#cancelAt = undefined; } cleanup() { @@ -203,7 +207,7 @@ export class Query implements QueryBase { eose(sub: string, conn: Readonly) { const qt = this.#tracing.find(a => a.id === sub && a.connId === conn.Id); qt?.gotEose(); - if (!this.leaveOpen) { + if (!this.#leaveOpen) { qt?.sendClose(); } } @@ -272,6 +276,7 @@ export class Query implements QueryBase { c.QueueReq(["REQ", qt.id, ...q.filters], () => qt.sentToRelay()); return qt; } + #reComputeFilters() { console.time("reComputeFilters"); this.#allFilters = flatMerge(this.#tracing.flatMap(a => a.filters).flatMap(expandFilter)); diff --git a/packages/app/src/System/RequestMerger.ts b/packages/app/src/System/RequestMerger.ts index 0a4ba5e1..bd588c25 100644 --- a/packages/app/src/System/RequestMerger.ts +++ b/packages/app/src/System/RequestMerger.ts @@ -7,7 +7,7 @@ import { distance } from "./Util"; */ const DiscriminatorKeys = ["since", "until", "limit", "search"]; -export function canMergeFilters(a: FlatReqFilter, b: FlatReqFilter): boolean { +export function canMergeFilters(a: FlatReqFilter | ReqFilter, b: FlatReqFilter | ReqFilter): boolean { const aObj = a as Record; const bObj = b as Record; for (const key of DiscriminatorKeys) { @@ -17,34 +17,21 @@ export function canMergeFilters(a: FlatReqFilter, b: FlatReqFilter): boolean { } } } - const keys1 = Object.keys(aObj); - const keys2 = Object.keys(bObj); - const maxKeys = keys1.length > keys2.length ? keys1 : keys2; - - let distance = 0; - for (const key of maxKeys) { - if (key in aObj && key in bObj) { - if (aObj[key] !== bObj[key]) { - distance++; - } - } else { - return false; - } - } - return distance <= 1; + return distance(aObj, bObj) <= 1; } export function mergeSimilar(filters: Array): Array { console.time("mergeSimilar"); const ret = []; - while (filters.length > 0) { - const current = filters.shift()!; + const fCopy = [...filters]; + while (fCopy.length > 0) { + const current = fCopy.shift()!; const mergeSet = [current]; - for (let i = 0; i < filters.length; i++) { - const f = filters[i]; + for (let i = 0; i < fCopy.length; i++) { + const f = fCopy[i]; if (mergeSet.every(v => canMergeFilters(v, f))) { - mergeSet.push(filters.splice(i, 1)[0]); + mergeSet.push(fCopy.splice(i, 1)[0]); i--; } } diff --git a/packages/app/src/System/index.ts b/packages/app/src/System/index.ts index 46be1f89..fd40e81e 100644 --- a/packages/app/src/System/index.ts +++ b/packages/app/src/System/index.ts @@ -38,7 +38,6 @@ export interface SystemSnapshot { id: string; filters: Array; subFilters: Array; - closing: boolean; }>; }