mirror of
https://github.com/signalapp/Signal-Desktop.git
synced 2025-12-24 20:26:24 +00:00
Keep messages in their own transaction in saveMessagesIndividually
This commit is contained in:
@@ -2731,7 +2731,6 @@ function saveMessage(
|
||||
_testOnlyAvoidNormalizingAttachments?: boolean;
|
||||
}
|
||||
): string {
|
||||
// NB: `saveMessagesIndividually` relies on `saveMessage` being atomic
|
||||
const { alreadyInTransaction, forceSave, jobToInsert, ourAci } = options;
|
||||
if (!alreadyInTransaction) {
|
||||
return db.transaction(() => {
|
||||
@@ -2901,6 +2900,10 @@ function saveMessage(
|
||||
} satisfies Omit<MessageTypeUnhydrated, 'json'>;
|
||||
|
||||
if (id && !forceSave) {
|
||||
if (normalizeAttachmentData) {
|
||||
saveMessageAttachments(db, message);
|
||||
}
|
||||
|
||||
const result = db
|
||||
.prepare(
|
||||
// UPDATE queries that set the value of a primary key column can be very slow when
|
||||
@@ -2919,16 +2922,12 @@ function saveMessage(
|
||||
return id;
|
||||
}
|
||||
|
||||
strictAssert(result.changes === 1, 'One row should have been changed');
|
||||
|
||||
if (normalizeAttachmentData) {
|
||||
saveMessageAttachments(db, message);
|
||||
}
|
||||
|
||||
if (jobToInsert) {
|
||||
insertJob(db, jobToInsert);
|
||||
}
|
||||
|
||||
strictAssert(result.changes === 1, 'One row should have been changed');
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
@@ -2991,10 +2990,7 @@ function saveMessagesIndividually(
|
||||
const failedIndices: Array<number> = [];
|
||||
arrayOfMessages.forEach((message, index) => {
|
||||
try {
|
||||
saveMessage(db, message, {
|
||||
...options,
|
||||
alreadyInTransaction: true,
|
||||
});
|
||||
saveMessage(db, message, options);
|
||||
} catch (e) {
|
||||
logger.error(
|
||||
'saveMessagesIndividually: failed to save message',
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
import { assert } from 'chai';
|
||||
import { v4 as generateGuid } from 'uuid';
|
||||
import { omit } from 'lodash';
|
||||
|
||||
import * as Bytes from '../Bytes';
|
||||
import type {
|
||||
@@ -637,4 +638,54 @@ describe('normalizes attachment references', () => {
|
||||
incrementalMac: undefined,
|
||||
});
|
||||
});
|
||||
|
||||
it('is resilient when called from saveMessagesIndividually to incorrect data', async () => {
|
||||
const attachment = {
|
||||
...composeAttachment(),
|
||||
key: {},
|
||||
randomKey: 'random',
|
||||
} as unknown as AttachmentType;
|
||||
|
||||
const attachments = [attachment];
|
||||
const message = composeMessage(Date.now(), {
|
||||
attachments,
|
||||
});
|
||||
|
||||
await DataWriter.saveMessages([message], {
|
||||
forceSave: true,
|
||||
ourAci: generateAci(),
|
||||
postSaveUpdates: () => Promise.resolve(),
|
||||
_testOnlyAvoidNormalizingAttachments: true,
|
||||
});
|
||||
|
||||
await DataWriter.saveMessagesIndividually([message], {
|
||||
ourAci: generateAci(),
|
||||
postSaveUpdates: () => Promise.resolve(),
|
||||
});
|
||||
|
||||
let messageFromDB = await DataReader.getMessageById(message.id);
|
||||
assert(messageFromDB, 'message was saved');
|
||||
assert.deepEqual(messageFromDB.attachments?.[0], attachment);
|
||||
|
||||
const attachmentWithoutKey = { ...attachment, key: undefined };
|
||||
await DataWriter.saveMessagesIndividually(
|
||||
[
|
||||
{
|
||||
...message,
|
||||
attachments: [attachmentWithoutKey],
|
||||
},
|
||||
],
|
||||
{
|
||||
ourAci: generateAci(),
|
||||
postSaveUpdates: () => Promise.resolve(),
|
||||
}
|
||||
);
|
||||
|
||||
messageFromDB = await DataReader.getMessageById(message.id);
|
||||
assert(messageFromDB, 'message was saved');
|
||||
assert.deepEqual(
|
||||
messageFromDB.attachments?.[0],
|
||||
omit(attachmentWithoutKey, 'randomKey')
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user