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 loadItem = async (key: string, ...args: LoadArgs) => {
const item = indexStore.get().get(key)
const stale = getItem(key)
const freshness = getFreshness(name, key)
// If we have an item, reload anyway if it's stale. If not, retry with exponential backoff
if (item) {
loadAttempts.delete(key)
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 have an item, reload if it's stale
if (stale && freshness > now() - 3600) {
return stale
}
// If we already are loading, await and return
if (pending.has(key)) {
await pending.get(key)
} else {
setFreshness(name, key, now())
const promise = load(key, ...args)
pending.set(key, promise)
await promise
pending.delete(key)
return pending.get(key)!.then(() => getItem(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) => {