-
-
Notifications
You must be signed in to change notification settings - Fork 364
Open
Description
follow up after testing the fix in #388, that one made it better (thanks!). However I still see cases where values that are fetched in the background gets lost.
This bug seems to be timing related and only happens when there are multiple background fetches in parallel. Following unit tests captures this behavior:
const c = new LRUCache<number, number, void>({
ttl: 10000,
max: 10,
ignoreFetchAbort: true,
allowStaleOnFetchAbort: true,
fetchMethod: async k => {
return new Promise(res => {
setTimeout(() => {
res(k)
}, 100 * k)
})
},
})
const ac = new AbortController()
// fails
const p2 = c.fetch(2, { signal: ac.signal })
const p1 = c.fetch(1, { signal: ac.signal })
// works
// const p1 = c.fetch(1, { signal: ac.signal })
// const p2 = c.fetch(2, { signal: ac.signal })
clock.advance(50)
await new Promise<void>(res => queueMicrotask(res))
ac.abort(new Error('gimme the stale value'))
t.equal(await p1, undefined)
t.equal(await p2, undefined)
t.equal(c.get(1, { allowStale: true }), undefined)
t.equal(c.get(2, { allowStale: true }), undefined)
clock.advance(100)
await new Promise<void>(res => queueMicrotask(res)).then(() => {})
t.equal(c.get(1), 1)
t.equal(c.get(2), undefined)
clock.advance(100)
await new Promise<void>(res => queueMicrotask(res)).then(() => {})
t.equal(c.get(1), 1)
t.equal(c.get(2), 2)
In above test two fetch calls are made. key 1 takes 100ms, key 2 takes 200 ms. After 150ms the 1 is available in cache, but after 250ms 2 still returns undefined.
Note that when changing the order of the fetch calls (commented out) then both keys are resolved correctly.
Metadata
Metadata
Assignees
Labels
No labels