Improve collection loader
This commit is contained in:
@@ -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) => {
|
||||||
|
|||||||
@@ -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> = {}) => ({
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user