Skip to content

Commit ec9c9cd

Browse files
committed
fix(cleanup): spend an attempt when the lowest unfinished image sweep stalls
The inline image handler continued without consuming an attempt whenever any chat hit the deadline, even when the lowest unfinished chat had stalled and the checkpoint could not advance, so the event could rerun forever. It now continues only after the checkpoint advanced or when the lowest unfinished chat is itself still advancing, and defers otherwise.
1 parent 8ca824b commit ec9c9cd

2 files changed

Lines changed: 19 additions & 1 deletion

File tree

‎apps/sim/lib/cleanup/chat-backend-cleanup-outbox.test.ts‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,4 +105,20 @@ describe('chat inline image cleanup', () => {
105105
expect(result).not.toMatchObject({ consumeAttempt: false })
106106
expect(context.checkpointPayload).not.toHaveBeenCalled()
107107
})
108+
109+
it('spends an attempt when the lowest unfinished chat stalls, though a later one continues', async () => {
110+
queueTableRows(copilotChats, [])
111+
mockSweepStoragePrefix.mockImplementation(async (prefix: string) => {
112+
if (prefix === prefixOf(chatIds[0])) return 'stalled'
113+
deadline.near = true
114+
return 'continue'
115+
})
116+
const context = outboxContext()
117+
118+
const result = await sweepImages({ chatIds: chatIds.slice(0, 2) }, context)
119+
120+
expect(result).toMatchObject({ outcome: 'deferred' })
121+
expect(result).not.toMatchObject({ consumeAttempt: false })
122+
expect(context.checkpointPayload).not.toHaveBeenCalled()
123+
})
108124
})

‎apps/sim/lib/cleanup/chat-backend-cleanup-outbox.ts‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,9 @@ export const chatBackendCleanupOutboxHandlers = {
123123
const unfinished = outcomes.findIndex((outcome) => outcome !== 'done')
124124
if (unfinished === -1) return
125125
if (unfinished > 0) await context.checkpointPayload({ swept: swept + unfinished })
126-
if (outcomes.includes('continue'))
126+
// A free rerun only after durable progress, or while the lowest unfinished chat itself advances;
127+
// a stalled one behind a continuing chat would otherwise rerun without end.
128+
if (unfinished > 0 || outcomes[unfinished] === 'continue')
127129
return continueOutboxHandler('Continuing chat inline image cleanup')
128130
return deferOutboxHandler('Chat inline image cleanup removed nothing from its listing')
129131
},

0 commit comments

Comments
 (0)