mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 09:10:45 +00:00
fix(sessions): preserve active route updates during maintenance
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
import fs from "node:fs/promises";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import {
|
||||
clearRuntimeConfigSnapshot,
|
||||
@@ -10,6 +9,7 @@ import {
|
||||
loadSessionStore,
|
||||
updateSessionStore,
|
||||
} from "openclaw/plugin-sdk/config-runtime";
|
||||
import { resolvePreferredOpenClawTmpDir } from "openclaw/plugin-sdk/temp-path";
|
||||
import { afterAll, afterEach, beforeAll, describe, expect, it } from "vitest";
|
||||
import { buildTelegramMessageContextForTest } from "./bot-message-context.test-harness.js";
|
||||
|
||||
@@ -20,7 +20,7 @@ function createSuiteTempRootTracker(params: { prefix: string }) {
|
||||
const children: string[] = [];
|
||||
return {
|
||||
async setup() {
|
||||
root = await fs.mkdtemp(path.join(os.tmpdir(), params.prefix));
|
||||
root = await fs.mkdtemp(path.join(resolvePreferredOpenClawTmpDir(), params.prefix));
|
||||
},
|
||||
async make(name: string) {
|
||||
if (!root) {
|
||||
|
||||
@@ -156,12 +156,19 @@ export function resolveMaintenanceConfigFromInput(
|
||||
export function pruneStaleEntries(
|
||||
store: Record<string, SessionEntry>,
|
||||
overrideMaxAgeMs?: number,
|
||||
opts: { log?: boolean; onPruned?: (params: { key: string; entry: SessionEntry }) => void } = {},
|
||||
opts: {
|
||||
log?: boolean;
|
||||
onPruned?: (params: { key: string; entry: SessionEntry }) => void;
|
||||
preserveKeys?: ReadonlySet<string>;
|
||||
} = {},
|
||||
): number {
|
||||
const maxAgeMs = overrideMaxAgeMs ?? resolveMaintenanceConfigFromInput().pruneAfterMs;
|
||||
const cutoffMs = Date.now() - maxAgeMs;
|
||||
let pruned = 0;
|
||||
for (const [key, entry] of Object.entries(store)) {
|
||||
if (opts.preserveKeys?.has(key)) {
|
||||
continue;
|
||||
}
|
||||
if (entry?.updatedAt != null && entry.updatedAt < cutoffMs) {
|
||||
opts.onPruned?.({ key, entry });
|
||||
delete store[key];
|
||||
@@ -265,11 +272,16 @@ export function capEntryCount(
|
||||
opts: {
|
||||
log?: boolean;
|
||||
onCapped?: (params: { key: string; entry: SessionEntry }) => void;
|
||||
preserveKeys?: ReadonlySet<string>;
|
||||
} = {},
|
||||
): number {
|
||||
const maxEntries = overrideMax ?? resolveMaintenanceConfigFromInput().maxEntries;
|
||||
const keys = Object.keys(store);
|
||||
if (keys.length <= maxEntries) {
|
||||
const preservedCount = opts.preserveKeys
|
||||
? Object.keys(store).filter((key) => opts.preserveKeys?.has(key)).length
|
||||
: 0;
|
||||
const maxRemovableEntries = Math.max(0, maxEntries - preservedCount);
|
||||
const keys = Object.keys(store).filter((key) => !opts.preserveKeys?.has(key));
|
||||
if (keys.length <= maxRemovableEntries) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -280,7 +292,7 @@ export function capEntryCount(
|
||||
return bTime - aTime;
|
||||
});
|
||||
|
||||
const toRemove = sorted.slice(maxEntries);
|
||||
const toRemove = sorted.slice(maxRemovableEntries);
|
||||
for (const key of toRemove) {
|
||||
const entry = store[key];
|
||||
if (entry) {
|
||||
|
||||
@@ -281,17 +281,22 @@ async function saveSessionStoreUnlocked(
|
||||
diskBudget,
|
||||
});
|
||||
} else {
|
||||
const preserveSessionKeys = opts?.activeSessionKey
|
||||
? new Set([opts.activeSessionKey])
|
||||
: undefined;
|
||||
// Prune stale entries and cap total count before serializing.
|
||||
const removedSessionFiles = new Map<string, string | undefined>();
|
||||
const pruned = pruneStaleEntries(store, maintenance.pruneAfterMs, {
|
||||
onPruned: ({ entry }) => {
|
||||
rememberRemovedSessionFile(removedSessionFiles, entry);
|
||||
},
|
||||
preserveKeys: preserveSessionKeys,
|
||||
});
|
||||
const capped = capEntryCount(store, maintenance.maxEntries, {
|
||||
onCapped: ({ entry }) => {
|
||||
rememberRemovedSessionFile(removedSessionFiles, entry);
|
||||
},
|
||||
preserveKeys: preserveSessionKeys,
|
||||
});
|
||||
const archivedDirs = new Set<string>();
|
||||
const referencedSessionIds = new Set(
|
||||
@@ -726,7 +731,6 @@ export async function updateLastRoute(params: {
|
||||
const store = loadSessionStore(storePath);
|
||||
const resolved = resolveSessionStoreEntry({ store, sessionKey });
|
||||
const existing = resolved.existing;
|
||||
const now = Date.now();
|
||||
const explicitContext = normalizeDeliveryContext(params.deliveryContext);
|
||||
const inlineContext = normalizeDeliveryContext({
|
||||
channel,
|
||||
|
||||
Reference in New Issue
Block a user