mirror of
https://github.com/stablyai/orca.git
synced 2026-10-04 00:02:21 +00:00
perf(renderer): release unrelated state during cache saves (#23021)
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
import { setImmediate } from 'node:timers/promises'
|
||||
import { afterEach, beforeEach, expect, it, vi } from 'vitest'
|
||||
import { createTestStore } from '../slices/store-test-helpers'
|
||||
import { debouncedSaveCache } from './cache-persistence'
|
||||
|
||||
const setGitHub = vi.fn()
|
||||
|
||||
beforeEach(() => {
|
||||
vi.useFakeTimers({ toFake: ['setTimeout', 'clearTimeout'] })
|
||||
setGitHub.mockReset()
|
||||
vi.stubGlobal('window', { api: { cache: { setGitHub } } })
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
vi.clearAllTimers()
|
||||
vi.useRealTimers()
|
||||
vi.unstubAllGlobals()
|
||||
})
|
||||
|
||||
it('releases unrelated discarded renderer state while the cache save is pending', async () => {
|
||||
const store = createTestStore()
|
||||
const schedule = () => {
|
||||
const drafts = { closedFile: Buffer.alloc(8 * 1024 * 1024, 65).toString('utf8') }
|
||||
const state = { ...store.getState(), editorDrafts: drafts }
|
||||
debouncedSaveCache(state)
|
||||
return { state: new WeakRef(state), drafts: new WeakRef(drafts) }
|
||||
}
|
||||
const discarded = schedule()
|
||||
if (!global.gc) {
|
||||
throw new Error('config/vitest.config.ts must pass --expose-gc')
|
||||
}
|
||||
for (let turn = 0; turn < 3; turn += 1) {
|
||||
await setImmediate()
|
||||
global.gc()
|
||||
}
|
||||
|
||||
expect(setGitHub).not.toHaveBeenCalled()
|
||||
expect(discarded.state.deref() === undefined).toBe(true)
|
||||
expect(discarded.drafts.deref() === undefined).toBe(true)
|
||||
vi.advanceTimersByTime(1000)
|
||||
expect(setGitHub).toHaveBeenCalledOnce()
|
||||
})
|
||||
|
||||
it('persists the latest requested cache maps once after the trailing second', () => {
|
||||
const state = createTestStore().getState()
|
||||
const first = { ...state, prCache: {}, issueCache: {} }
|
||||
const latest = { ...state, prCache: {}, issueCache: {} }
|
||||
debouncedSaveCache(first)
|
||||
vi.advanceTimersByTime(999)
|
||||
expect(setGitHub).not.toHaveBeenCalled()
|
||||
|
||||
debouncedSaveCache(latest)
|
||||
vi.advanceTimersByTime(999)
|
||||
expect(setGitHub).not.toHaveBeenCalled()
|
||||
vi.advanceTimersByTime(1)
|
||||
expect(setGitHub).toHaveBeenCalledOnce()
|
||||
expect(setGitHub.mock.calls[0][0]).toEqual({
|
||||
cache: { pr: latest.prCache, issue: latest.issueCache }
|
||||
})
|
||||
expect(setGitHub.mock.calls[0][0].cache.pr).toBe(latest.prCache)
|
||||
expect(setGitHub.mock.calls[0][0].cache.issue).toBe(latest.issueCache)
|
||||
vi.advanceTimersByTime(1000)
|
||||
expect(setGitHub).toHaveBeenCalledOnce()
|
||||
})
|
||||
@@ -5,12 +5,14 @@ let saveTimer: ReturnType<typeof setTimeout> | null = null
|
||||
/** Schedules the renderer's single trailing GitHub cache persistence write. */
|
||||
export function debouncedSaveCache(state: AppState): void {
|
||||
clearTimeout(saveTimer ?? undefined)
|
||||
// Keep unrelated renderer state out of the pending timer's closure.
|
||||
const { prCache, issueCache } = state
|
||||
saveTimer = setTimeout(() => {
|
||||
saveTimer = null
|
||||
window.api.cache.setGitHub({
|
||||
cache: {
|
||||
pr: state.prCache,
|
||||
issue: state.issueCache
|
||||
pr: prCache,
|
||||
issue: issueCache
|
||||
}
|
||||
})
|
||||
}, 1000)
|
||||
|
||||
Reference in New Issue
Block a user