Skip to content

Commit 316d9da

Browse files
author
Eric Wheeler
committed
refactor: make say() transactional
Refactors the say() method in Task.ts to ensure message updates are atomic. The mutation logic for the last message is moved inside the modifyClineMessages() callback. This makes the find, update, and save operations a single atomic transaction, preventing race conditions and ensuring data integrity. Signed-off-by: Eric Wheeler <[email protected]>
1 parent 038fc63 commit 316d9da

File tree

1 file changed

+23
-15
lines changed

1 file changed

+23
-15
lines changed

src/core/task/Task.ts

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -728,7 +728,13 @@ export class Task extends EventEmitter<ClineEvents> {
728728
}
729729

730730
if (partial !== undefined) {
731-
const lastMessage = this.clineMessages.at(-1)
731+
let lastMessage = this.clineMessages.at(-1)
732+
733+
if (lastMessage === undefined) {
734+
throw new Error(
735+
`[RooCode#say] task ${this.taskId}.${this.instanceId}: clineMessages is empty? Please report this bug.`,
736+
)
737+
}
732738

733739
const isUpdatingPreviousPartial =
734740
lastMessage && lastMessage.partial && lastMessage.type === "say" && lastMessage.say === type
@@ -764,23 +770,25 @@ export class Task extends EventEmitter<ClineEvents> {
764770
// This is the complete version of a previously partial
765771
// message, so replace the partial with the complete version.
766772
if (isUpdatingPreviousPartial) {
767-
if (!options.isNonInteractive) {
768-
this.lastMessageTs = lastMessage.ts
769-
}
770-
771-
lastMessage.text = text
772-
lastMessage.images = images
773-
lastMessage.partial = false
774-
lastMessage.progressStatus = progressStatus
775-
776773
// Instead of streaming partialMessage events, we do a save
777774
// and post like normal to persist to disk.
778-
await this.modifyClineMessages(async () => {
779-
return this.clineMessages
780-
})
775+
await this.modifyClineMessages(async (messages) => {
776+
lastMessage = messages.at(-1) // update ref for transaction
777+
if (lastMessage) {
778+
if (!options.isNonInteractive) {
779+
this.lastMessageTs = lastMessage.ts
780+
}
781781

782-
// More performant than an entire `postStateToWebview`.
783-
this.updateClineMessage(lastMessage)
782+
lastMessage.text = text
783+
lastMessage.images = images
784+
lastMessage.partial = false
785+
lastMessage.progressStatus = progressStatus
786+
787+
// More performant than an entire `postStateToWebview`.
788+
this.updateClineMessage(lastMessage)
789+
}
790+
return messages
791+
})
784792
} else {
785793
// This is a new and complete message, so add it like normal.
786794
const sayTs = Date.now()

0 commit comments

Comments
 (0)