From 337e7f63aa6f2be2c2bce092de0fff950ae75a91 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Fri, 8 May 2026 21:05:30 +0100 Subject: [PATCH] fix: raise memory sqlite busy timeout --- extensions/memory-core/src/memory/manager-db.ts | 4 +++- .../memory-core/src/memory/manager.readonly-recovery.test.ts | 4 ++-- extensions/memory-core/src/memory/qmd-manager.ts | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/extensions/memory-core/src/memory/manager-db.ts b/extensions/memory-core/src/memory/manager-db.ts index 234c9005b5e..1fe0f737347 100644 --- a/extensions/memory-core/src/memory/manager-db.ts +++ b/extensions/memory-core/src/memory/manager-db.ts @@ -7,6 +7,8 @@ import { requireNodeSqlite, } from "openclaw/plugin-sdk/memory-core-host-engine-storage"; +export const MEMORY_SQLITE_BUSY_TIMEOUT_MS = 30_000; + export function openMemoryDatabaseAtPath(dbPath: string, allowExtension: boolean): DatabaseSync { const dir = path.dirname(dbPath); ensureDir(dir); @@ -16,7 +18,7 @@ export function openMemoryDatabaseAtPath(dbPath: string, allowExtension: boolean // busy_timeout is per-connection and resets to 0 on restart. // Set it on every open so concurrent processes retry instead of // failing immediately with SQLITE_BUSY. - db.exec("PRAGMA busy_timeout = 5000"); + db.exec(`PRAGMA busy_timeout = ${MEMORY_SQLITE_BUSY_TIMEOUT_MS}`); return db; } diff --git a/extensions/memory-core/src/memory/manager.readonly-recovery.test.ts b/extensions/memory-core/src/memory/manager.readonly-recovery.test.ts index 1faab2c7898..83e44034f2a 100644 --- a/extensions/memory-core/src/memory/manager.readonly-recovery.test.ts +++ b/extensions/memory-core/src/memory/manager.readonly-recovery.test.ts @@ -4,7 +4,7 @@ import path from "node:path"; import type { DatabaseSync } from "node:sqlite"; import type { OpenClawConfig } from "openclaw/plugin-sdk/memory-core-host-engine-foundation"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; -import { openMemoryDatabaseAtPath } from "./manager-db.js"; +import { MEMORY_SQLITE_BUSY_TIMEOUT_MS, openMemoryDatabaseAtPath } from "./manager-db.js"; import { _createMemorySyncControlConfigForTests, enqueueMemoryTargetedSessionSync, @@ -219,7 +219,7 @@ describe("memory manager readonly recovery", () => { | { busy_timeout?: number; timeout?: number } | undefined; const busyTimeout = row?.busy_timeout ?? row?.timeout; - expect(busyTimeout).toBe(5000); + expect(busyTimeout).toBe(MEMORY_SQLITE_BUSY_TIMEOUT_MS); db.close(); }); diff --git a/extensions/memory-core/src/memory/qmd-manager.ts b/extensions/memory-core/src/memory/qmd-manager.ts index 1fa087fd41a..a10e5d43863 100644 --- a/extensions/memory-core/src/memory/qmd-manager.ts +++ b/extensions/memory-core/src/memory/qmd-manager.ts @@ -2218,7 +2218,7 @@ export class QmdMemoryManager implements MemorySearchManager { this.db = new DatabaseSync(this.indexPath, { readOnly: true }); // busy_timeout is per-connection; set it on every open so concurrent // processes retry instead of failing immediately with SQLITE_BUSY. - // Use a lower value than the write path (5 s) because this read-only + // Use a lower value than the memory write path because this read-only // connection runs synchronous queries on the main thread via DatabaseSync. // In WAL mode readers rarely block, so 1 s is a safe upper bound. this.db.exec("PRAGMA busy_timeout = 1000");