mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-18 17:04:46 +00:00
fix(sessions): skip durable fsync for session store
This commit is contained in:
@@ -10,6 +10,7 @@ Docs: https://docs.openclaw.ai
|
||||
- Discord/voice: keep TTS playback running when another user starts speaking, ignore new capture during playback to avoid feedback loops, and downgrade expected receive-stream aborts to verbose diagnostics.
|
||||
- Telegram: treat successful same-chat `message` tool outbound sends during an inbound telegram turn as delivered when deciding whether to emit the rewritten silent reply fallback (#78685). Thanks @neeravmakwana.
|
||||
- Gateway/tasks: reconcile stale CLI run-context tasks whose live run context disappeared even when a child session row remains, and apply the default bounded reload deferral timeout to channel hot reloads so stale task records cannot block Discord/Slack/Telegram reloads forever.
|
||||
- Gateway/sessions: keep session-store index writes atomic while skipping durable fsync inside the writer lock, reducing cron and channel-turn starvation on slow filesystems. Fixes #73655. Thanks @mmartoccia.
|
||||
- Discord/voice: make `openclaw channels capabilities --channel discord --target channel:<id>` and `channels status --probe` audit voice-channel permissions, including auto-join targets, so missing Connect/Speak/Read Message History permissions show up before `/vc join`.
|
||||
- Channels CLI: make `openclaw channels list` channel-only — drop the `Auth providers (OAuth + API keys)` block (use `openclaw models auth list`), drop the per-provider usage/quota fetch and the `--no-usage` flag (use `openclaw status` or `openclaw models list`), add `--all` to surface bundled-unconfigured, catalog-not-installed, and catalog-installed-but-unconfigured channels, and render explicit `installed` / `configured` / `enabled` tags per row plus an `origin` + `installed` field in JSON. Fixes WeCom-class catalog channels disappearing from `--all` when installed on disk but not yet configured. (#78456) Thanks @sliverp.
|
||||
- CLI/cron: add computed `status` field to `cron list --json` and `cron show <id> --json` output, mirroring the human-readable status column (disabled/running/ok/error/skipped/idle) so external tooling can determine job state without re-deriving it from raw state fields. (#78701) Thanks @aweiker.
|
||||
|
||||
@@ -337,6 +337,31 @@ describe("session store writer queue", () => {
|
||||
writeSpy.mockRestore();
|
||||
});
|
||||
|
||||
it("keeps session store writes atomic while skipping durable fsync inside the writer lock", async () => {
|
||||
const key = "agent:main:no-fsync";
|
||||
const { storePath } = await makeTmpStore({
|
||||
[key]: { sessionId: "s-no-fsync", updatedAt: Date.now(), counter: 0 },
|
||||
});
|
||||
|
||||
const writeSpy = vi.spyOn(jsonFiles, "writeTextAtomic");
|
||||
await updateSessionStore(
|
||||
storePath,
|
||||
async (store) => {
|
||||
const entry = store[key] as Record<string, unknown>;
|
||||
entry.counter = 1;
|
||||
},
|
||||
{ skipMaintenance: true },
|
||||
);
|
||||
|
||||
expect(writeSpy).toHaveBeenCalledTimes(1);
|
||||
expect(writeSpy).toHaveBeenCalledWith(
|
||||
storePath,
|
||||
expect.any(String),
|
||||
expect.objectContaining({ durable: false, mode: 0o600 }),
|
||||
);
|
||||
writeSpy.mockRestore();
|
||||
});
|
||||
|
||||
it("multiple consecutive errors do not permanently poison the queue", async () => {
|
||||
const key = "agent:main:multi-err";
|
||||
const { storePath } = await makeTmpStore({
|
||||
|
||||
@@ -499,7 +499,7 @@ async function writeSessionStoreAtomic(params: {
|
||||
store: Record<string, SessionEntry>;
|
||||
serialized: string;
|
||||
}): Promise<void> {
|
||||
await writeTextAtomic(params.storePath, params.serialized, { mode: 0o600 });
|
||||
await writeTextAtomic(params.storePath, params.serialized, { durable: false, mode: 0o600 });
|
||||
updateSessionStoreWriteCaches({
|
||||
storePath: params.storePath,
|
||||
store: params.store,
|
||||
|
||||
Reference in New Issue
Block a user