fix(opencode): use file times for truncation cleanup (#40987)
Co-authored-by: Dax <mail@thdxr.com>
This commit is contained in:
committed by
GitHub
parent
31c5c4e924
commit
d468201952
@@ -6,7 +6,6 @@ import type { Agent } from "../agent/agent"
|
|||||||
import { FSUtil } from "@opencode-ai/core/fs-util"
|
import { FSUtil } from "@opencode-ai/core/fs-util"
|
||||||
import { evaluate } from "@/permission/evaluate"
|
import { evaluate } from "@/permission/evaluate"
|
||||||
import { Config } from "@/config/config"
|
import { Config } from "@/config/config"
|
||||||
import { Identifier } from "../id/id"
|
|
||||||
import { ToolID } from "./schema"
|
import { ToolID } from "./schema"
|
||||||
import { TRUNCATION_DIR } from "./truncation-dir"
|
import { TRUNCATION_DIR } from "./truncation-dir"
|
||||||
|
|
||||||
@@ -52,16 +51,17 @@ const layer = Layer.effect(
|
|||||||
const fs = yield* FSUtil.Service
|
const fs = yield* FSUtil.Service
|
||||||
|
|
||||||
const cleanup = Effect.fn("Truncate.cleanup")(function* () {
|
const cleanup = Effect.fn("Truncate.cleanup")(function* () {
|
||||||
const cutoff = Identifier.timestamp(
|
const cutoff = Date.now() - Duration.toMillis(RETENTION)
|
||||||
Identifier.create("tool", "ascending", Date.now() - Duration.toMillis(RETENTION)),
|
|
||||||
)
|
|
||||||
const entries = yield* fs.readDirectory(TRUNCATION_DIR).pipe(
|
const entries = yield* fs.readDirectory(TRUNCATION_DIR).pipe(
|
||||||
Effect.map((all) => all.filter((name) => name.startsWith("tool_"))),
|
Effect.map((all) => all.filter((name) => name.startsWith("tool_"))),
|
||||||
Effect.catch(() => Effect.succeed([])),
|
Effect.catch(() => Effect.succeed([])),
|
||||||
)
|
)
|
||||||
for (const entry of entries) {
|
for (const entry of entries) {
|
||||||
if (Identifier.timestamp(entry) >= cutoff) continue
|
const file = path.join(TRUNCATION_DIR, entry)
|
||||||
yield* fs.remove(path.join(TRUNCATION_DIR, entry)).pipe(Effect.catch(() => Effect.void))
|
const info = yield* fs.stat(file).pipe(Effect.catch(() => Effect.succeed(undefined)))
|
||||||
|
const mtime = info && Option.getOrUndefined(info.mtime)
|
||||||
|
if (!mtime || mtime.getTime() >= cutoff) continue
|
||||||
|
yield* fs.remove(file).pipe(Effect.catch(() => Effect.void))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -242,18 +242,20 @@ describe("Truncate", () => {
|
|||||||
describe("cleanup", () => {
|
describe("cleanup", () => {
|
||||||
const DAY_MS = 24 * 60 * 60 * 1000
|
const DAY_MS = 24 * 60 * 60 * 1000
|
||||||
|
|
||||||
it.live("deletes files older than 7 days and preserves recent files", () =>
|
it.live("uses file mtime when IDs wrap", () =>
|
||||||
Effect.gen(function* () {
|
Effect.gen(function* () {
|
||||||
const svc = yield* Truncate.Service
|
const svc = yield* Truncate.Service
|
||||||
const fs = yield* FileSystem.FileSystem
|
const fs = yield* FileSystem.FileSystem
|
||||||
|
|
||||||
yield* fs.makeDirectory(Truncate.DIR, { recursive: true })
|
yield* fs.makeDirectory(Truncate.DIR, { recursive: true })
|
||||||
|
|
||||||
const old = path.join(Truncate.DIR, Identifier.create("tool", "ascending", Date.now() - 10 * DAY_MS))
|
const old = path.join(Truncate.DIR, Identifier.create("tool", "ascending", 2 ** 36 - 1))
|
||||||
const recent = path.join(Truncate.DIR, Identifier.create("tool", "ascending", Date.now() - 3 * DAY_MS))
|
const recent = path.join(Truncate.DIR, Identifier.create("tool", "ascending", 2 ** 36 + 1))
|
||||||
|
|
||||||
yield* writeFileStringScoped(old, "old content")
|
yield* writeFileStringScoped(old, "old content")
|
||||||
yield* writeFileStringScoped(recent, "recent content")
|
yield* writeFileStringScoped(recent, "recent content")
|
||||||
|
yield* fs.utimes(old, new Date(), new Date(Date.now() - 10 * DAY_MS))
|
||||||
|
yield* fs.utimes(recent, new Date(), new Date(Date.now() - 3 * DAY_MS))
|
||||||
yield* svc.cleanup()
|
yield* svc.cleanup()
|
||||||
|
|
||||||
expect(yield* fs.exists(old)).toBe(false)
|
expect(yield* fs.exists(old)).toBe(false)
|
||||||
|
|||||||
Reference in New Issue
Block a user