Skip to content

Commit 897bac5

Browse files
committed
fix(sessions): skip durable fsync for session store
1 parent 01dd593 commit 897bac5

3 files changed

Lines changed: 27 additions & 1 deletion

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ Docs: https://docs.openclaw.ai
1010
- 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.
1111
- 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.
1212
- 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.
13+
- 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.
1314
- 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`.
1415
- 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.
1516
- 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.

src/config/sessions/sessions.test.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,31 @@ describe("session store writer queue", () => {
337337
writeSpy.mockRestore();
338338
});
339339

340+
it("keeps session store writes atomic while skipping durable fsync inside the writer lock", async () => {
341+
const key = "agent:main:no-fsync";
342+
const { storePath } = await makeTmpStore({
343+
[key]: { sessionId: "s-no-fsync", updatedAt: Date.now(), counter: 0 },
344+
});
345+
346+
const writeSpy = vi.spyOn(jsonFiles, "writeTextAtomic");
347+
await updateSessionStore(
348+
storePath,
349+
async (store) => {
350+
const entry = store[key] as Record<string, unknown>;
351+
entry.counter = 1;
352+
},
353+
{ skipMaintenance: true },
354+
);
355+
356+
expect(writeSpy).toHaveBeenCalledTimes(1);
357+
expect(writeSpy).toHaveBeenCalledWith(
358+
storePath,
359+
expect.any(String),
360+
expect.objectContaining({ durable: false, mode: 0o600 }),
361+
);
362+
writeSpy.mockRestore();
363+
});
364+
340365
it("multiple consecutive errors do not permanently poison the queue", async () => {
341366
const key = "agent:main:multi-err";
342367
const { storePath } = await makeTmpStore({

src/config/sessions/store.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -499,7 +499,7 @@ async function writeSessionStoreAtomic(params: {
499499
store: Record<string, SessionEntry>;
500500
serialized: string;
501501
}): Promise<void> {
502-
await writeTextAtomic(params.storePath, params.serialized, { mode: 0o600 });
502+
await writeTextAtomic(params.storePath, params.serialized, { durable: false, mode: 0o600 });
503503
updateSessionStoreWriteCaches({
504504
storePath: params.storePath,
505505
store: params.store,

0 commit comments

Comments
 (0)