Improve collection loader

This commit is contained in:
Jon Staab
2024-09-05 16:29:23 -07:00
parent 3868daa04e
commit b9c73ea826
3 changed files with 34 additions and 35 deletions
+32 -28
View File
@@ -20,41 +20,45 @@ export const collection = <T, LoadArgs extends any[]>({
const loadAttempts = new Map<string, number>() const loadAttempts = new Map<string, number>()
const loadItem = async (key: string, ...args: LoadArgs) => { const loadItem = async (key: string, ...args: LoadArgs) => {
const item = indexStore.get().get(key) const stale = getItem(key)
const freshness = getFreshness(name, key) const freshness = getFreshness(name, key)
// If we have an item, reload anyway if it's stale. If not, retry with exponential backoff // If we have an item, reload if it's stale
if (item) { if (stale && freshness > now() - 3600) {
loadAttempts.delete(key) return stale
if (freshness > now() - 3600) {
return item
}
} else {
const attempt = loadAttempts.get(key) || 0
if (freshness > now() - Math.pow(2, attempt)) {
return undefined
}
loadAttempts.set(key, attempt + 1)
} }
// If we already are loading, await and return
if (pending.has(key)) { if (pending.has(key)) {
await pending.get(key) return pending.get(key)!.then(() => getItem(key))
} else {
setFreshness(name, key, now())
const promise = load(key, ...args)
pending.set(key, promise)
await promise
pending.delete(key)
} }
return indexStore.get().get(key) const attempt = loadAttempts.get(key) || 0
// Use exponential backoff to throttle attempts
if (freshness > now() - Math.pow(2, attempt)) {
return stale
}
loadAttempts.set(key, attempt + 1)
setFreshness(name, key, now())
const promise = load(key, ...args)
pending.set(key, promise)
await promise
pending.delete(key)
const fresh = getItem(key)
if (fresh) {
loadAttempts.delete(key)
}
return fresh
} }
const deriveItem = (key: Maybe<string>, ...args: LoadArgs) => { const deriveItem = (key: Maybe<string>, ...args: LoadArgs) => {
+1
View File
@@ -14,6 +14,7 @@ export type AppContext = {
authTimeout: number authTimeout: number
requestTimeout: number requestTimeout: number
dufflepudUrl?: string dufflepudUrl?: string
indexerRelays?: string[]
} }
export const getDefaultNetContext = (overrides: Partial<NetContext> = {}) => ({ export const getDefaultNetContext = (overrides: Partial<NetContext> = {}) => ({
+1 -7
View File
@@ -15,12 +15,6 @@ import {relays, relaysByUrl} from './relays'
export const INDEXED_KINDS = [PROFILE, RELAYS, INBOX_RELAYS, FOLLOWS] export const INDEXED_KINDS = [PROFILE, RELAYS, INBOX_RELAYS, FOLLOWS]
export const INDEXER_RELAYS = [
'wss://purplepag.es/',
'wss://relay.damus.io/',
'wss://relay.nostr.band/',
]
export enum RelayMode { export enum RelayMode {
Read = "read", Read = "read",
Write = "write", Write = "write",
@@ -442,7 +436,7 @@ export const getPubkeyRelays = (pubkey: string, mode?: string) => {
} }
} }
export const getIndexerRelays = () => INDEXER_RELAYS export const getIndexerRelays = () => ctx.app.indexerRelays || getFallbackRelays()
export const getFallbackRelays = throttleWithValue(300, () => export const getFallbackRelays = throttleWithValue(300, () =>
relays.get().filter(r => getRelayQuality(r.url) >= 0.5).map(r => r.url) relays.get().filter(r => getRelayQuality(r.url) >= 0.5).map(r => r.url)