From c213a49228e978b3b5a6c0abce45b282f6fe7933 Mon Sep 17 00:00:00 2001 From: Juha Paananen Date: Tue, 30 Jan 2024 20:50:05 +0200 Subject: [PATCH] Use select-for-update to make sure board compaction is not run while loading board No strong reason to suppose this concurrency would be harmful but the opposite isn't proven either so better safe than sorry. --- backend/src/board-store.ts | 2 +- backend/src/compact-history.ts | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/backend/src/board-store.ts b/backend/src/board-store.ts index b460dafe8..3c82f1756 100644 --- a/backend/src/board-store.ts +++ b/backend/src/board-store.ts @@ -29,7 +29,7 @@ with allow_lists as ( from board_access a where a.board_id = b.id ) as allow_list - from board b + from board b for update ) select id, jsonb_set (content - 'accessPolicy', '{accessPolicy}', cast(case when allow_list is null then 'null' else (json_build_object('allowList', allow_list, 'publicRead', public_read, 'publicWrite', public_write)) end as jsonb)) as content diff --git a/backend/src/compact-history.ts b/backend/src/compact-history.ts index 151e07258..6546550e1 100644 --- a/backend/src/compact-history.ts +++ b/backend/src/compact-history.ts @@ -15,10 +15,13 @@ import { verifyContinuityFromMetas, } from "./board-store" import { inTransaction } from "./db" +import { sleep } from "../../common/src/sleep" export async function quickCompactBoardHistory(id: Id) { let fallback = false const result = inTransaction(async (client) => { + // Lock the board to prevent loading the board while compacting + await client.query("select 1 from board where id=$1 for update", [id]) const bundleMetas = await getBoardHistoryBundleMetas(client, id) if (bundleMetas.length === 0) return const consistent = verifyContinuityFromMetas(id, 0, bundleMetas)