mirror of
https://github.com/stablyai/orca.git
synced 2026-11-01 01:27:35 +00:00
fix(wsl-mover): retry a failed listing, never a record another window was refused
Review of #32343: not-main-window can't clear by waiting, while a listing failure is transient. Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -106,12 +106,34 @@ describe('WSL move renderer store rewrites', () => {
|
||||
expect(client.record).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('never throws when the move list is unavailable', async () => {
|
||||
client.list.mockRejectedValue(new Error('no bridge'))
|
||||
const warn = vi.spyOn(console, 'warn').mockImplementation(() => {})
|
||||
await expect((await loadRunner()).runWslMoveRendererStoreRewrites()).resolves.toBeUndefined()
|
||||
expect(warn).toHaveBeenCalled()
|
||||
warn.mockRestore()
|
||||
it('never throws when the move list is unavailable, and asks again later', async () => {
|
||||
vi.useFakeTimers()
|
||||
try {
|
||||
client.list.mockRejectedValueOnce(new Error('main not ready')).mockResolvedValue([])
|
||||
const warn = vi.spyOn(console, 'warn').mockImplementation(() => {})
|
||||
await expect((await loadRunner()).runWslMoveRendererStoreRewrites()).resolves.toBeUndefined()
|
||||
expect(warn).toHaveBeenCalled()
|
||||
await vi.advanceTimersByTimeAsync(2_000)
|
||||
expect(client.list).toHaveBeenCalledTimes(2)
|
||||
await vi.advanceTimersByTimeAsync(120_000)
|
||||
expect(client.list).toHaveBeenCalledTimes(2)
|
||||
warn.mockRestore()
|
||||
} finally {
|
||||
vi.useRealTimers()
|
||||
}
|
||||
})
|
||||
|
||||
it('does not retry a record another window was refused', async () => {
|
||||
vi.useFakeTimers()
|
||||
try {
|
||||
client.list.mockResolvedValue([move({ storeIds: ['quick-open-history'] })])
|
||||
client.record.mockResolvedValue({ recorded: false, reason: 'not-main-window' })
|
||||
await (await loadRunner()).runWslMoveRendererStoreRewrites()
|
||||
await vi.advanceTimersByTimeAsync(120_000)
|
||||
expect(client.record).toHaveBeenCalledTimes(1)
|
||||
} finally {
|
||||
vi.useRealTimers()
|
||||
}
|
||||
})
|
||||
|
||||
it('adds a host copy beside each moved entry, then records every store', async () => {
|
||||
|
||||
@@ -82,8 +82,9 @@ function writeAppliedMarker(marker: string): void {
|
||||
}
|
||||
}
|
||||
|
||||
// Main's refusals that a later call can clear; the rest mean the store is no longer pending.
|
||||
const RETRYABLE_RECORD_REASONS: ReadonlySet<string> = new Set(['gated-off', 'failed', 'not-main-window'])
|
||||
// Main's refusals a later call can clear. Another window (`not-main-window`) never becomes the main
|
||||
// one, and the rest mean the store is no longer pending.
|
||||
const RETRYABLE_RECORD_REASONS: ReadonlySet<string> = new Set(['gated-off', 'failed'])
|
||||
|
||||
/** True when a store's ledger entry still has to land: the move stays unfinished until it does. */
|
||||
async function rewriteMove(move: WslMovePendingRendererRewrite): Promise<boolean> {
|
||||
@@ -144,8 +145,9 @@ async function rewritePendingMoves(): Promise<boolean> {
|
||||
unrecorded = (await rewriteMove(move)) || unrecorded
|
||||
}
|
||||
} catch (error) {
|
||||
// No bridge to ask (a web client): nothing here could ever record, so no retry.
|
||||
// Transient (main not ready yet); the backoff bounds a bridge that never answers.
|
||||
console.warn('[wsl-move] Could not list renderer rewrites:', error)
|
||||
unrecorded = true
|
||||
}
|
||||
return unrecorded
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user