diff options
| author | Adam Soltys <[email protected]> | 2026-11-02 09:31:22 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-11-02 09:31:22 -0700 |
| commit | 071f8db3bd7799abe4a6acf7c32f107eef0d00c2 (patch) | |
| tree | 3ccfff716224a3e9801064cb8439fe94b9fd86c3 /src | |
| parent | df4d28e29776349c0b2aef6d5367cace6aa25822 (diff) | |
| download | coinosv3-071f8db3bd7799abe4a6acf7c32f107eef0d00c2.tar.gz coinosv3-071f8db3bd7799abe4a6acf7c32f107eef0d00c2.zip | |
A quoted note, or the post a reply answers, is asked for from the near relays first — the reference's own hints, ours, its author's — and from the wide net of public and archive relays only once those have come back empty, or after 1.2 s if they are slow about it. Asked all at once, as before, every quote and every reply's parent went out to a dozen relays, and in the Conversations view, where each row has a parent, half of all REQs in twenty seconds on the live app — three hundred, to 47 relays — were lookups of notes our own relays answered in the first beat. tools/relay-budget-test.js adds a far relay: the six quotes our relay holds are never asked of it, and the one only it holds is still found there
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VMan6TFgisGKUDhdStLUvs
Diffstat (limited to 'src')
| -rw-r--r-- | src/features/messages.js | 33 |
1 files changed, 24 insertions, 9 deletions
diff --git a/src/features/messages.js b/src/features/messages.js index 79526b8..b7982c6 100644 --- a/src/features/messages.js +++ b/src/features/messages.js @@ -8584,20 +8584,35 @@ export function messagesFeature(ctx) { } } } - // All at once, first answer wins: asked in turn, a note on a far relay - // took longer than the feed waits for a row. + // The near relays first — the reference's hints, ours, the author's own + // — and the wide net only once those have come back empty, or after a + // moment if they are slow about it (asked in turn, a note on a far relay + // took longer than the feed waits for a row; asked all at once, every + // quoted note and every reply's parent went to a dozen relays, and the + // Conversations view spent half its REQs — three hundred in twenty + // seconds — on notes our own relays answered in the first beat). + const WIDE_AFTER_MS = 1200; function findNote(ref) { const ask = (relays) => askNote(relays, ref.id); const near = [...new Set([...(ref.relays || []), ...zapRelays()])]; const authors = [...new Set([ref.author, ...(ref.authors || [])].filter(Boolean))]; - const asks = [ - askNote(near, ref.id, ref.relays || []), - ...authors.map((a) => relaysOf(a).catch(() => []).then((rs) => ask(rs.filter((r) => !near.includes(r))))), - ask(WIDE_RELAYS.filter((r) => !near.includes(r))), - ]; return new Promise((resolve) => { - let left = asks.length; - for (const a of asks) a.then((ev) => { if (ev) resolve(ev); else if (--left === 0) resolve(null); }); + let done = false; + const found = (ev) => { if (!done && ev) { done = true; resolve(ev); } }; + const nearAsks = [ + askNote(near, ref.id, ref.relays || []), + ...authors.map((a) => relaysOf(a).catch(() => []).then((rs) => ask(rs.filter((r) => !near.includes(r))))), + ]; + for (const a of nearAsks) a.then(found); + const nearDone = Promise.all(nearAsks); + let wide = null; + const goWide = () => { + if (done || wide) return; + wide = ask(WIDE_RELAYS.filter((r) => !near.includes(r))); + wide.then(found); + }; + const timer = setTimeout(goWide, WIDE_AFTER_MS); + nearDone.then(() => { clearTimeout(timer); if (done) return; goWide(); wide.then((ev) => { if (!done) { done = true; resolve(ev || null); } }); }); }); } function quotedNote(ref) { |
