From 15d180a785f7edfc5db582e9211d44a7336ef2c4 Mon Sep 17 00:00:00 2001 From: trevor-signal <131492920+trevor-signal@users.noreply.github.com> Date: Thu, 2 Oct 2025 12:28:35 -0400 Subject: [PATCH] Avoid deadlock when processing deletes and edits concurrently --- ts/sql/Server.ts | 29 ++++++++++++++++++++++++++--- ts/util/modifyTargetMessage.ts | 4 ++-- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/ts/sql/Server.ts b/ts/sql/Server.ts index 25078dd7ba..c35dec0d09 100644 --- a/ts/sql/Server.ts +++ b/ts/sql/Server.ts @@ -8758,8 +8758,9 @@ function saveEditedMessages( alreadyInTransaction: true, }); - for (const { conversationId, messageId, readStatus, sentAt } of history) { - const [query, params] = sql` + try { + for (const { conversationId, messageId, readStatus, sentAt } of history) { + const [query, params] = sql` INSERT INTO edited_messages ( conversationId, messageId, @@ -8773,7 +8774,29 @@ function saveEditedMessages( ); `; - db.prepare(query).run(params); + db.prepare(query).run(params); + } + } catch (e) { + const [messageExistsQuery, messageExistsParams] = sql` + SELECT EXISTS( + SELECT 1 FROM messages + WHERE messages.id = ${mainMessage.id} + ); + `; + const messageExists = db + .prepare(messageExistsQuery, { + pluck: true, + }) + .get(messageExistsParams); + + if (messageExists !== 1) { + logger.warn( + 'saveEditedMessages: save failed because message does not exist' + ); + } else { + // Some other, unknown error + throw e; + } } })(); } diff --git a/ts/util/modifyTargetMessage.ts b/ts/util/modifyTargetMessage.ts index 025016152a..a5b551c46f 100644 --- a/ts/util/modifyTargetMessage.ts +++ b/ts/util/modifyTargetMessage.ts @@ -365,8 +365,8 @@ export async function modifyTargetMessage( if (!isFirstRun && !skipEdits) { const edits = Edits.forMessage(message.attributes); log.info(`${logId}: ${edits.length} edits in second run`); - await Promise.all( - edits.map(editAttributes => + edits.map(editAttributes => + drop( conversation.queueJob('modifyTargetMessage/edits', () => handleEditMessage(message.attributes, editAttributes) )