mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-08 14:48:28 +00:00
Memory: chain forced QMD queue and fail over on busy index
This commit is contained in:
committed by
Vignesh
parent
0d60ef6fef
commit
c741d008dd
@@ -85,6 +85,7 @@ export class QmdMemoryManager implements MemorySearchManager {
|
||||
private updateTimer: NodeJS.Timeout | null = null;
|
||||
private pendingUpdate: Promise<void> | null = null;
|
||||
private queuedForcedUpdate: Promise<void> | null = null;
|
||||
private queuedForcedRuns = 0;
|
||||
private closed = false;
|
||||
private db: SqliteDatabase | null = null;
|
||||
private lastUpdateAt: number | null = null;
|
||||
@@ -386,36 +387,35 @@ export class QmdMemoryManager implements MemorySearchManager {
|
||||
clearInterval(this.updateTimer);
|
||||
this.updateTimer = null;
|
||||
}
|
||||
this.queuedForcedRuns = 0;
|
||||
await this.pendingUpdate?.catch(() => undefined);
|
||||
await this.queuedForcedUpdate?.catch(() => undefined);
|
||||
if (this.db) {
|
||||
this.db.close();
|
||||
this.db = null;
|
||||
}
|
||||
}
|
||||
|
||||
private async runUpdate(reason: string, force?: boolean): Promise<void> {
|
||||
private async runUpdate(
|
||||
reason: string,
|
||||
force?: boolean,
|
||||
opts?: { fromForcedQueue?: boolean },
|
||||
): Promise<void> {
|
||||
if (this.closed) {
|
||||
return;
|
||||
}
|
||||
if (this.pendingUpdate) {
|
||||
if (force) {
|
||||
if (!this.queuedForcedUpdate) {
|
||||
this.queuedForcedUpdate = this.pendingUpdate
|
||||
.catch(() => undefined)
|
||||
.then(async () => {
|
||||
if (this.closed) {
|
||||
return;
|
||||
}
|
||||
await this.runUpdate(`${reason}:queued`, true);
|
||||
})
|
||||
.finally(() => {
|
||||
this.queuedForcedUpdate = null;
|
||||
});
|
||||
}
|
||||
return this.queuedForcedUpdate;
|
||||
return this.enqueueForcedUpdate(reason);
|
||||
}
|
||||
return this.pendingUpdate;
|
||||
}
|
||||
if (this.queuedForcedUpdate && !opts?.fromForcedQueue) {
|
||||
if (force) {
|
||||
return this.enqueueForcedUpdate(reason);
|
||||
}
|
||||
return this.queuedForcedUpdate;
|
||||
}
|
||||
if (this.shouldSkipUpdate(force)) {
|
||||
return;
|
||||
}
|
||||
@@ -446,6 +446,24 @@ export class QmdMemoryManager implements MemorySearchManager {
|
||||
await this.pendingUpdate;
|
||||
}
|
||||
|
||||
private enqueueForcedUpdate(reason: string): Promise<void> {
|
||||
this.queuedForcedRuns += 1;
|
||||
if (!this.queuedForcedUpdate) {
|
||||
this.queuedForcedUpdate = this.drainForcedUpdates(reason).finally(() => {
|
||||
this.queuedForcedUpdate = null;
|
||||
});
|
||||
}
|
||||
return this.queuedForcedUpdate;
|
||||
}
|
||||
|
||||
private async drainForcedUpdates(reason: string): Promise<void> {
|
||||
await this.pendingUpdate?.catch(() => undefined);
|
||||
while (!this.closed && this.queuedForcedRuns > 0) {
|
||||
this.queuedForcedRuns -= 1;
|
||||
await this.runUpdate(`${reason}:queued`, true, { fromForcedQueue: true });
|
||||
}
|
||||
}
|
||||
|
||||
private async runQmd(
|
||||
args: string[],
|
||||
opts?: { timeoutMs?: number },
|
||||
@@ -577,7 +595,7 @@ export class QmdMemoryManager implements MemorySearchManager {
|
||||
} catch (err) {
|
||||
if (this.isSqliteBusyError(err)) {
|
||||
log.debug(`qmd index is busy while resolving doc path: ${String(err)}`);
|
||||
return null;
|
||||
throw this.createQmdBusyError(err);
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
@@ -862,6 +880,11 @@ export class QmdMemoryManager implements MemorySearchManager {
|
||||
return normalized.includes("sqlite_busy") || normalized.includes("database is locked");
|
||||
}
|
||||
|
||||
private createQmdBusyError(err: unknown): Error {
|
||||
const message = err instanceof Error ? err.message : String(err);
|
||||
return new Error(`qmd index busy while reading results: ${message}`);
|
||||
}
|
||||
|
||||
private async waitForPendingUpdateBeforeSearch(): Promise<void> {
|
||||
const pending = this.pendingUpdate;
|
||||
if (!pending) {
|
||||
|
||||
Reference in New Issue
Block a user