mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-12 07:20:45 +00:00
Cron: clean run-log write queue entries (#23968)
* Cron: clean run-log write queue entries * Changelog: add cron run-log write-queue cleanup note
This commit is contained in:
@@ -71,6 +71,7 @@ Docs: https://docs.openclaw.ai
|
||||
- Cron/Schedule: for `every` jobs, prefer `lastRunAtMs + everyMs` when still in the future after restarts, then fall back to anchor scheduling for catch-up windows, so NEXT timing matches the last successful cadence. (#22895) Thanks @SidQin-cyber.
|
||||
- Cron/Service: execute manual `cron.run` jobs outside the cron lock (while still persisting started/finished state atomically) so `cron.list` and `cron.status` remain responsive during long forced runs. (#23628) Thanks @dsgraves.
|
||||
- Cron/Timer: keep a watchdog recheck timer armed while `onTimer` is actively executing so the scheduler continues polling even if a due-run tick stalls for an extended period. (#23628) Thanks @dsgraves.
|
||||
- Cron/Run log: clean up settled per-path run-log write queue entries so long-running cron uptime does not retain stale promise bookkeeping in memory.
|
||||
- Cron/Isolation: force fresh session IDs for isolated cron runs so `sessionTarget="isolated"` executions never reuse prior run context. (#23470) Thanks @echoVic.
|
||||
- Plugins/Install: strip `workspace:*` devDependency entries from copied plugin manifests before `npm install --omit=dev`, preventing `EUNSUPPORTEDPROTOCOL` install failures for npm-published channel plugins (including Feishu and MS Teams).
|
||||
- Feishu/Plugins: restore bundled Feishu SDK availability for global installs and strip `openclaw: workspace:*` from plugin `devDependencies` during plugin-version sync so npm-installed Feishu plugins do not fail dependency install. (#23611, #23645, #23603)
|
||||
|
||||
@@ -2,7 +2,12 @@ import fs from "node:fs/promises";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { appendCronRunLog, readCronRunLogEntries, resolveCronRunLogPath } from "./run-log.js";
|
||||
import {
|
||||
appendCronRunLog,
|
||||
getPendingCronRunLogWriteCountForTests,
|
||||
readCronRunLogEntries,
|
||||
resolveCronRunLogPath,
|
||||
} from "./run-log.js";
|
||||
|
||||
describe("cron run log", () => {
|
||||
async function withRunLogDir(prefix: string, run: (dir: string) => Promise<void>) {
|
||||
@@ -185,4 +190,18 @@ describe("cron run log", () => {
|
||||
expect(entries[1]?.usage?.input_tokens).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
it("cleans up pending-write bookkeeping after appends complete", async () => {
|
||||
await withRunLogDir("openclaw-cron-log-pending-", async (dir) => {
|
||||
const logPath = path.join(dir, "runs", "job-cleanup.jsonl");
|
||||
await appendCronRunLog(logPath, {
|
||||
ts: 1,
|
||||
jobId: "job-cleanup",
|
||||
action: "finished",
|
||||
status: "ok",
|
||||
});
|
||||
|
||||
expect(getPendingCronRunLogWriteCountForTests()).toBe(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -27,6 +27,10 @@ export function resolveCronRunLogPath(params: { storePath: string; jobId: string
|
||||
|
||||
const writesByPath = new Map<string, Promise<void>>();
|
||||
|
||||
export function getPendingCronRunLogWriteCountForTests() {
|
||||
return writesByPath.size;
|
||||
}
|
||||
|
||||
async function pruneIfNeeded(filePath: string, opts: { maxBytes: number; keepLines: number }) {
|
||||
const stat = await fs.stat(filePath).catch(() => null);
|
||||
if (!stat || stat.size <= opts.maxBytes) {
|
||||
@@ -63,7 +67,13 @@ export async function appendCronRunLog(
|
||||
});
|
||||
});
|
||||
writesByPath.set(resolved, next);
|
||||
await next;
|
||||
try {
|
||||
await next;
|
||||
} finally {
|
||||
if (writesByPath.get(resolved) === next) {
|
||||
writesByPath.delete(resolved);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export async function readCronRunLogEntries(
|
||||
|
||||
Reference in New Issue
Block a user