mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 05:20:43 +00:00
fix(plugin-state): preserve fresh evicted entries
This commit is contained in:
@@ -61,6 +61,7 @@ Docs: https://docs.openclaw.ai
|
||||
|
||||
### Fixes
|
||||
|
||||
- Plugins/runtime state: keep the key being registered when namespace eviction runs in the same millisecond as existing entries, so `register` and `registerIfAbsent` do not report success while evicting their own fresh value. Thanks @vincentkoc.
|
||||
- Control UI/Talk: make failed Talk startup errors dismissable and clear the stale Talk error state when dismissed, so missing realtime voice provider configuration does not leave a permanent chat banner. Fixes #77071. Thanks @ijoshdavis.
|
||||
- Control UI/Talk: stop and clear failed realtime Talk sessions when dismissing runtime error banners, so the next Talk click starts a fresh session instead of only stopping the stale one. Thanks @vincentkoc.
|
||||
- Control UI/Talk: retry from a failed realtime Talk session on the next Talk click instead of requiring a separate stale-session stop click first. Thanks @vincentkoc.
|
||||
|
||||
@@ -259,6 +259,7 @@ function createStatements(db: DatabaseSync): PluginStateStatements {
|
||||
FROM plugin_state_entries
|
||||
WHERE plugin_id = ?
|
||||
AND namespace = ?
|
||||
AND entry_key <> ?
|
||||
AND (expires_at IS NULL OR expires_at > ?)
|
||||
ORDER BY created_at ASC, entry_key ASC
|
||||
LIMIT ?
|
||||
@@ -387,6 +388,7 @@ function enforcePostRegisterLimits(params: {
|
||||
namespace: string;
|
||||
maxEntries: number;
|
||||
now: number;
|
||||
protectedKey: string;
|
||||
}): void {
|
||||
const namespaceCount = countRow(
|
||||
params.store.statements.countLiveNamespace.get(
|
||||
@@ -399,6 +401,7 @@ function enforcePostRegisterLimits(params: {
|
||||
params.store.statements.deleteOldestNamespace.run(
|
||||
params.pluginId,
|
||||
params.namespace,
|
||||
params.protectedKey,
|
||||
params.now,
|
||||
namespaceCount - params.maxEntries,
|
||||
);
|
||||
@@ -446,6 +449,7 @@ export function pluginStateRegister(params: {
|
||||
namespace: params.namespace,
|
||||
maxEntries: params.maxEntries,
|
||||
now,
|
||||
protectedKey: params.key,
|
||||
});
|
||||
});
|
||||
} catch (error) {
|
||||
@@ -488,6 +492,7 @@ export function pluginStateRegisterIfAbsent(params: {
|
||||
namespace: params.namespace,
|
||||
maxEntries: params.maxEntries,
|
||||
now,
|
||||
protectedKey: params.key,
|
||||
});
|
||||
return true;
|
||||
});
|
||||
|
||||
@@ -264,6 +264,40 @@ describe("plugin state keyed store", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("keeps the just-registered key when namespace eviction timestamps tie", async () => {
|
||||
await withOpenClawTestState({ label: "plugin-state-eviction-tie-register" }, async () => {
|
||||
vi.useFakeTimers();
|
||||
vi.setSystemTime(1000);
|
||||
const store = createPluginStateKeyedStore<number>("discord", {
|
||||
namespace: "evict-tie-register",
|
||||
maxEntries: 1,
|
||||
});
|
||||
|
||||
await store.register("z", 1);
|
||||
await store.register("a", 2);
|
||||
|
||||
await expect(store.entries()).resolves.toMatchObject([{ key: "a", value: 2 }]);
|
||||
await expect(store.lookup("z")).resolves.toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
it("keeps a same-millisecond registerIfAbsent claim during namespace eviction", async () => {
|
||||
await withOpenClawTestState({ label: "plugin-state-eviction-tie-claim" }, async () => {
|
||||
vi.useFakeTimers();
|
||||
vi.setSystemTime(1000);
|
||||
const store = createPluginStateKeyedStore<number>("discord", {
|
||||
namespace: "evict-tie-claim",
|
||||
maxEntries: 1,
|
||||
});
|
||||
|
||||
await expect(store.registerIfAbsent("z", 1)).resolves.toBe(true);
|
||||
await expect(store.registerIfAbsent("a", 2)).resolves.toBe(true);
|
||||
|
||||
await expect(store.entries()).resolves.toMatchObject([{ key: "a", value: 2 }]);
|
||||
await expect(store.lookup("z")).resolves.toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
it("rejects when the per-plugin live row ceiling would be exceeded without evicting siblings", async () => {
|
||||
await withOpenClawTestState({ label: "plugin-state-plugin-limit" }, async () => {
|
||||
seedPluginStateEntriesForTests([
|
||||
|
||||
Reference in New Issue
Block a user