Fix db error from concurrent processing of call link update sync

This commit is contained in:
ayumi-signal
2025-06-30 16:58:26 -07:00
committed by GitHub
parent 746b22d3dc
commit bcb1a614ea
6 changed files with 217 additions and 40 deletions

View File

@@ -53,6 +53,7 @@ import type { AttachmentBackupJobType } from '../types/AttachmentBackup';
import type { GifType } from '../components/fun/panels/FunPanelGifs';
import type { NotificationProfileType } from '../types/NotificationProfile';
import type { DonationReceipt } from '../types/Donations';
import type { InsertOrUpdateCallLinkFromSyncResult } from './server/callLinks';
export type ReadableDB = Database & { __readable_db: never };
export type WritableDB = ReadableDB & { __writable_db: never };
@@ -1030,8 +1031,10 @@ type WritableInterface = {
markCallHistoryMissed(callIds: ReadonlyArray<string>): void;
getRecentStaleRingsAndMarkOlderMissed(): ReadonlyArray<MaybeStaleCallHistory>;
insertCallLink(callLink: CallLinkType): void;
insertOrUpdateCallLinkFromSync(
callLink: CallLinkType
): InsertOrUpdateCallLinkFromSyncResult;
updateCallLink(callLink: CallLinkType): void;
updateCallLinkAdminKeyByRoomId(roomId: string, adminKey: string): void;
updateCallLinkState(
roomId: string,
callLinkState: CallLinkStateType

View File

@@ -213,8 +213,8 @@ import {
getCallLinkRecordByRoomId,
insertCallLink,
insertDefunctCallLink,
insertOrUpdateCallLinkFromSync,
updateCallLink,
updateCallLinkAdminKeyByRoomId,
updateCallLinkState,
updateDefunctCallLink,
} from './server/callLinks';
@@ -546,8 +546,8 @@ export const DataWriter: ServerWritableInterface = {
saveCallHistory,
markCallHistoryMissed,
insertCallLink,
insertOrUpdateCallLinkFromSync,
updateCallLink,
updateCallLinkAdminKeyByRoomId,
updateCallLinkState,
beginDeleteAllCallLinks,
beginDeleteCallLink,

View File

@@ -121,6 +121,41 @@ export function insertCallLink(db: WritableDB, callLink: CallLinkType): void {
_insertCallLink(db, callLink);
}
export type InsertOrUpdateCallLinkFromSyncResult = Readonly<{
callLink: CallLinkType;
inserted: boolean;
updated: boolean;
}>;
export function insertOrUpdateCallLinkFromSync(
db: WritableDB,
callLink: CallLinkType
): InsertOrUpdateCallLinkFromSyncResult {
const { roomId, adminKey } = callLink;
return db.transaction(() => {
const existingCallLink = getCallLinkByRoomId(db, roomId);
if (existingCallLink) {
if (adminKey && adminKey !== existingCallLink.adminKey) {
updateCallLinkAdminKeyByRoomId(db, roomId, adminKey);
return {
callLink: { ...existingCallLink, adminKey },
inserted: false,
updated: true,
};
}
return {
callLink: existingCallLink,
inserted: false,
updated: false,
};
}
insertCallLink(db, callLink);
return { callLink, inserted: true, updated: false };
})();
}
export function updateCallLink(db: WritableDB, callLink: CallLinkType): void {
const { roomId, rootKey } = callLink;
assertRoomIdMatchesRootKey(roomId, rootKey);