mirror of
https://github.com/stablyai/orca.git
synced 2026-09-30 00:03:15 +00:00
perf(jira): preserve replacement attachment download singleflight
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
import { beforeEach, describe, expect, it } from 'vitest'
|
||||
import {
|
||||
_resetAttachmentImageCache,
|
||||
clearAttachmentImagesForSite,
|
||||
getCachedAttachmentDataUrl,
|
||||
loadAttachmentDataUrlWithCache
|
||||
} from './attachment-image-cache'
|
||||
|
||||
type Image = { dataUrl: string; byteSize: number } | null
|
||||
function deferredImage() {
|
||||
let resolve!: (image: Image) => void
|
||||
let reject!: (error: Error) => void
|
||||
const promise = new Promise<Image>((done, fail) => {
|
||||
resolve = done
|
||||
reject = fail
|
||||
})
|
||||
return { promise, resolve, reject }
|
||||
}
|
||||
|
||||
beforeEach(_resetAttachmentImageCache)
|
||||
|
||||
describe.each(['site', 'all'] as const)('attachment download after clearing %s', (scope) => {
|
||||
it.each(['success', 'empty', 'failure'] as const)(
|
||||
'keeps the replacement singleflight when the old download completes with %s',
|
||||
async (outcome) => {
|
||||
const old = deferredImage()
|
||||
const replacement = deferredImage()
|
||||
let downloads = 0
|
||||
const load = () => {
|
||||
downloads += 1
|
||||
return downloads === 1 ? old.promise : replacement.promise
|
||||
}
|
||||
const args = { siteId: 'site-a', attachmentId: 'image-1', load }
|
||||
const first = loadAttachmentDataUrlWithCache(args).catch(() => 'old failure')
|
||||
clearAttachmentImagesForSite(scope === 'site' ? 'site-a' : undefined)
|
||||
const second = loadAttachmentDataUrlWithCache(args)
|
||||
expect(downloads).toBe(2)
|
||||
|
||||
if (outcome === 'failure') {
|
||||
old.reject(new Error('old failure'))
|
||||
} else {
|
||||
old.resolve(outcome === 'empty' ? null : { dataUrl: 'old image', byteSize: 3 })
|
||||
}
|
||||
expect(await first).toBe(
|
||||
outcome === 'failure' ? 'old failure' : outcome === 'empty' ? null : 'old image'
|
||||
)
|
||||
expect(getCachedAttachmentDataUrl('site-a', 'image-1')).toBeNull()
|
||||
|
||||
const third = loadAttachmentDataUrlWithCache(args)
|
||||
expect(downloads).toBe(2)
|
||||
replacement.resolve({ dataUrl: 'new image', byteSize: 3 })
|
||||
expect(await second).toBe('new image')
|
||||
expect(await third).toBe('new image')
|
||||
expect(getCachedAttachmentDataUrl('site-a', 'image-1')).toBe('new image')
|
||||
}
|
||||
)
|
||||
})
|
||||
@@ -133,7 +133,10 @@ export async function loadAttachmentDataUrlWithCache(args: {
|
||||
}
|
||||
return loaded.dataUrl
|
||||
} finally {
|
||||
inFlight.delete(key)
|
||||
// A cleared generation no longer owns the current download's singleflight slot.
|
||||
if (currentEpoch(args.siteId) === epochAtStart) {
|
||||
inFlight.delete(key)
|
||||
}
|
||||
}
|
||||
})()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user