Reach a feed back only as far as its shallowest relay has answered

This commit is contained in:
Coracle-Bot 2026-09-25 07:14:40 +00:00
parent 57e0c4985d
commit 201836a246

View file

@ -482,6 +482,9 @@ export const makeFeed = ({
// How far back the feed has been answered for, which decides whether an event is ready to render. // How far back the feed has been answered for, which decides whether an event is ready to render.
let reached = at let reached = at
// A span reaches only as far as its shallowest relay, so every one of them has to have answered.
const relayCount = new Set(relays).size
const insertEvents = (newEvents: Iterable<TrustedEvent>) => { const insertEvents = (newEvents: Iterable<TrustedEvent>) => {
const added: TrustedEvent[] = [] const added: TrustedEvent[] = []
@ -547,7 +550,7 @@ export const makeFeed = ({
const unsubscribers = syncFeed({relays, filters, addEvents, removeEvents}) const unsubscribers = syncFeed({relays, filters, addEvents, removeEvents})
// Each relay answers a limit for itself, so a page runs out where the relay that gave least ran out. // Each relay answers a limit for itself, so a page runs out where the relay that gave least ran out.
const loadSpan = async (extension: Filter, onAnswer?: (event: TrustedEvent) => void) => { const loadSpan = async (extension: Filter, onCover?: (timestamp: number) => void) => {
let complete = false let complete = false
const pages = new Map<string, {count: number; lowest: number}>() const pages = new Map<string, {count: number; lowest: number}>()
@ -562,7 +565,9 @@ export const makeFeed = ({
pages.set(url, {count: 1, lowest: event.created_at}) pages.set(url, {count: 1, lowest: event.created_at})
} }
onAnswer?.(event) if (pages.size === relayCount) {
onCover?.(Math.max(...Array.from(pages.values(), page => page.lowest)))
}
} }
const found = await network.get().request({ const found = await network.get().request({
@ -592,10 +597,8 @@ export const makeFeed = ({
const until = oldest const until = oldest
const since = until - olderInterval const since = until - olderInterval
// A page comes back newest first, so each event proves the stretch above it has been answered. // A page comes back newest first, so a relay's lowest answer proves the stretch above it.
const {found, complete, pages} = await loadSpan({since, until, limit: PAGE_SIZE}, event => const {found, complete, pages} = await loadSpan({since, until, limit: PAGE_SIZE}, reach)
reach(event.created_at),
)
// A relay that answered with less than its limit has covered its whole span. // A relay that answered with less than its limit has covered its whole span.
let edge: Maybe<number> let edge: Maybe<number>
@ -641,16 +644,15 @@ export const makeFeed = ({
} }
// What the repository already holds is an answer too, so a page of it renders before any relay replies. // What the repository already holds is an answer too, so a page of it renders before any relay replies.
const stored = relays const stored = relays.map(url =>
.flatMap(url => Array.from(getEventsForUrl(url, filters))) Array.from(getEventsForUrl(url, filters)).sort(compareEventsAsc).slice(-PAGE_SIZE),
.sort(compareEventsAsc) )
.slice(-PAGE_SIZE)
if (stored.length > 0) { if (stored.every(page => page.length > 0)) {
reach(stored[0].created_at) reach(Math.max(...stored.map(page => page[0].created_at)))
} }
addEvents(stored) addEvents(stored.flat())
return { return {
events, events,