mirror of https://github.com/openclaw/openclaw.git
fix(memory): restore readonly recovery helper seams
This commit is contained in:
parent
ba4116e6a9
commit
59866dd253
|
|
@ -85,6 +85,18 @@ const IGNORED_MEMORY_WATCH_DIR_NAMES = new Set([
|
|||
|
||||
const log = createSubsystemLogger("memory");
|
||||
|
||||
export function openMemoryDatabaseAtPath(dbPath: string, allowExtension: boolean): DatabaseSync {
|
||||
const dir = path.dirname(dbPath);
|
||||
ensureDir(dir);
|
||||
const { DatabaseSync } = requireNodeSqlite();
|
||||
const db = new DatabaseSync(dbPath, { allowExtension });
|
||||
// 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");
|
||||
return db;
|
||||
}
|
||||
|
||||
function shouldIgnoreMemoryWatchPath(watchPath: string): boolean {
|
||||
const normalized = path.normalize(watchPath);
|
||||
const parts = normalized.split(path.sep).map((segment) => segment.trim().toLowerCase());
|
||||
|
|
@ -259,19 +271,7 @@ export abstract class MemoryManagerSyncOps {
|
|||
|
||||
protected openDatabase(): DatabaseSync {
|
||||
const dbPath = resolveUserPath(this.settings.store.path);
|
||||
return this.openDatabaseAtPath(dbPath);
|
||||
}
|
||||
|
||||
private openDatabaseAtPath(dbPath: string): DatabaseSync {
|
||||
const dir = path.dirname(dbPath);
|
||||
ensureDir(dir);
|
||||
const { DatabaseSync } = requireNodeSqlite();
|
||||
const db = new DatabaseSync(dbPath, { allowExtension: this.settings.store.vector.enabled });
|
||||
// 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");
|
||||
return db;
|
||||
return openMemoryDatabaseAtPath(dbPath, this.settings.store.vector.enabled);
|
||||
}
|
||||
|
||||
private seedEmbeddingCache(sourceDb: DatabaseSync): void {
|
||||
|
|
@ -1149,7 +1149,7 @@ export abstract class MemoryManagerSyncOps {
|
|||
}): Promise<void> {
|
||||
const dbPath = resolveUserPath(this.settings.store.path);
|
||||
const tempDbPath = `${dbPath}.tmp-${randomUUID()}`;
|
||||
const tempDb = this.openDatabaseAtPath(tempDbPath);
|
||||
const tempDb = openMemoryDatabaseAtPath(tempDbPath, this.settings.store.vector.enabled);
|
||||
|
||||
const originalDb = this.db;
|
||||
let originalDbClosed = false;
|
||||
|
|
@ -1164,7 +1164,7 @@ export abstract class MemoryManagerSyncOps {
|
|||
|
||||
const restoreOriginalState = () => {
|
||||
if (originalDbClosed) {
|
||||
this.db = this.openDatabaseAtPath(dbPath);
|
||||
this.db = openMemoryDatabaseAtPath(dbPath, this.settings.store.vector.enabled);
|
||||
} else {
|
||||
this.db = originalDb;
|
||||
}
|
||||
|
|
@ -1237,7 +1237,7 @@ export abstract class MemoryManagerSyncOps {
|
|||
|
||||
await this.swapIndexFiles(dbPath, tempDbPath);
|
||||
|
||||
this.db = this.openDatabaseAtPath(dbPath);
|
||||
this.db = openMemoryDatabaseAtPath(dbPath, this.settings.store.vector.enabled);
|
||||
this.vectorReady = null;
|
||||
this.vector.available = null;
|
||||
this.vector.loadError = undefined;
|
||||
|
|
|
|||
|
|
@ -726,7 +726,54 @@ export class MemoryIndexManager extends MemoryManagerEmbeddingOps implements Mem
|
|||
sessionFiles?: string[];
|
||||
progress?: (update: MemorySyncProgressUpdate) => void;
|
||||
}): Promise<void> {
|
||||
await runMemorySyncWithReadonlyRecovery(this, params);
|
||||
const thisManager = this;
|
||||
const state: MemoryReadonlyRecoveryState = {
|
||||
get closed() {
|
||||
return thisManager.closed;
|
||||
},
|
||||
get db() {
|
||||
return thisManager.db;
|
||||
},
|
||||
set db(value) {
|
||||
thisManager.db = value;
|
||||
},
|
||||
get vectorReady() {
|
||||
return thisManager.vectorReady;
|
||||
},
|
||||
set vectorReady(value) {
|
||||
thisManager.vectorReady = value;
|
||||
},
|
||||
vector: this.vector,
|
||||
get readonlyRecoveryAttempts() {
|
||||
return thisManager.readonlyRecoveryAttempts;
|
||||
},
|
||||
set readonlyRecoveryAttempts(value) {
|
||||
thisManager.readonlyRecoveryAttempts = value;
|
||||
},
|
||||
get readonlyRecoverySuccesses() {
|
||||
return thisManager.readonlyRecoverySuccesses;
|
||||
},
|
||||
set readonlyRecoverySuccesses(value) {
|
||||
thisManager.readonlyRecoverySuccesses = value;
|
||||
},
|
||||
get readonlyRecoveryFailures() {
|
||||
return thisManager.readonlyRecoveryFailures;
|
||||
},
|
||||
set readonlyRecoveryFailures(value) {
|
||||
thisManager.readonlyRecoveryFailures = value;
|
||||
},
|
||||
get readonlyRecoveryLastError() {
|
||||
return thisManager.readonlyRecoveryLastError;
|
||||
},
|
||||
set readonlyRecoveryLastError(value) {
|
||||
thisManager.readonlyRecoveryLastError = value;
|
||||
},
|
||||
runSync: (nextParams) => this.runSync(nextParams),
|
||||
openDatabase: () => this.openDatabase(),
|
||||
ensureSchema: () => this.ensureSchema(),
|
||||
readMeta: () => this.readMeta() ?? undefined,
|
||||
};
|
||||
await runMemorySyncWithReadonlyRecovery(state, params);
|
||||
}
|
||||
|
||||
async readFile(params: {
|
||||
|
|
|
|||
Loading…
Reference in New Issue