Skip to content

Commit d078e82

Browse files
committed
refactor(chat): thread the recoverable-abort outcome through the send result
Replaces the restorableCleanupAbortRef reset choreography with a widened startSendMessage return ('recoverable_cleanup_abort'), so the restore decision is ordinary data flow and the second caller cannot leave a stale flag behind.
1 parent ed4ea7c commit d078e82

1 file changed

Lines changed: 14 additions & 21 deletions

File tree

  • apps/sim/app/workspace/[workspaceId]/home/hooks

apps/sim/app/workspace/[workspaceId]/home/hooks/use-chat.ts

Lines changed: 14 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1345,12 +1345,6 @@ export function useChat(
13451345
const queueDispatchActionsRef = useRef<QueueDispatchAction[]>([])
13461346
const queueDispatchTaskRef = useRef<Promise<void> | null>(null)
13471347
const queueDispatchEpochRef = useRef(0)
1348-
/**
1349-
* Set when the in-flight dispatch was killed by the unmount cleanup before
1350-
* reaching the server. Lets the restore path re-queue the message across the
1351-
* epoch bump that same cleanup performs.
1352-
*/
1353-
const restorableCleanupAbortRef = useRef(false)
13541348
const queueDispatchLoopRef = useRef<() => Promise<void>>(async () => {})
13551349
const enqueueQueueDispatchRef = useRef<(action: QueueDispatchActionInput) => Promise<void>>(
13561350
async () => {}
@@ -3842,14 +3836,12 @@ export function useChat(
38423836
(err instanceof Error && err.name === 'AbortError') || sendAbortSignal?.aborted === true
38433837
if (sendWasAborted) {
38443838
if (sendAbortSignal?.reason === 'unmount:client_cleanup' && !sendReachedServer) {
3845-
/* The mount-settling effect cycle (Suspense hide/reveal) ran the
3846-
unmount cleanup while this send was still pre-dispatch. Nothing
3847-
reached the server, so the send is fully recoverable: withdraw
3848-
the optimistic pair and report not-consumed so the queued entry
3849-
is restored and re-dispatched when effects re-run. */
3839+
/* The mount-settling remount ran the unmount cleanup while this
3840+
send was still pre-dispatch. Nothing reached the server, so the
3841+
send is fully recoverable: withdraw the optimistic pair and
3842+
report the distinct outcome so the dispatcher redelivers it. */
38503843
rollbackOptimisticSend()
3851-
restorableCleanupAbortRef.current = true
3852-
return false
3844+
return 'recoverable_cleanup_abort'
38533845
}
38543846
return consumedByTranscript
38553847
}
@@ -4491,15 +4483,18 @@ export function useChat(
44914483
useMothershipQueueStore.getState().remove(dispatchChatKey, msg.id)
44924484
}
44934485

4494-
const restoreQueuedMessage = (handoff?: QueuedSendHandoffSeed) => {
4486+
const restoreQueuedMessage = (
4487+
handoff?: QueuedSendHandoffSeed,
4488+
recoverableCleanupAbort = false
4489+
) => {
44954490
if (!handoff) {
44964491
clearQueuedSendHandoffState(msg.id)
44974492
}
44984493
clearQueuedSendHandoffClaim(msg.id)
44994494
if (!removedFromQueue) {
45004495
return
45014496
}
4502-
if (options.epoch !== queueDispatchEpochRef.current && !restorableCleanupAbortRef.current) {
4497+
if (options.epoch !== queueDispatchEpochRef.current && !recoverableCleanupAbort) {
45034498
return
45044499
}
45054500
// If the user explicitly removed this message during dispatch, honor
@@ -4515,7 +4510,7 @@ export function useChat(
45154510
key is the stable chat id). Attachment payloads exceed what the
45164511
handoff carries, so they fall back to the queue restore. */
45174512
if (
4518-
restorableCleanupAbortRef.current &&
4513+
recoverableCleanupAbort &&
45194514
dispatchChatKey.startsWith(PENDING_CHAT_KEY_PREFIX) &&
45204515
!msg.fileAttachments?.length
45214516
) {
@@ -4552,8 +4547,7 @@ export function useChat(
45524547
// between dispatch scheduling and this send.
45534548
const liveMsg = queueAtSend[currentIndex]
45544549
activeQueuedSendHandoff = options.queuedSendHandoff ?? liveMsg.queuedSendHandoff
4555-
restorableCleanupAbortRef.current = false
4556-
const consumed = await startSendMessage(
4550+
const sendResult = await startSendMessage(
45574551
liveMsg.content,
45584552
liveMsg.fileAttachments,
45594553
liveMsg.contexts,
@@ -4562,13 +4556,12 @@ export function useChat(
45624556
activeQueuedSendHandoff
45634557
)
45644558

4565-
if (!consumed) {
4566-
restoreQueuedMessage(activeQueuedSendHandoff)
4559+
if (sendResult !== true) {
4560+
restoreQueuedMessage(activeQueuedSendHandoff, sendResult === 'recoverable_cleanup_abort')
45674561
}
45684562
} catch {
45694563
restoreQueuedMessage(activeQueuedSendHandoff)
45704564
} finally {
4571-
restorableCleanupAbortRef.current = false
45724565
setDispatchingHeadId((current) => (current === msg.id ? null : current))
45734566
queuedMessageDispatchIdsRef.current.delete(msg.id)
45744567
userRemovedDuringDispatchRef.current.delete(msg.id)

0 commit comments

Comments
 (0)