Moves effect logging, observability, runtime utilities, flags, installation version info, and process utilities from opencode to core package. This enables better code sharing across packages and establishes core as the single source of truth for foundational utilities. All internal imports updated to use @opencode-ai/core paths for consistency.
60 lines
1.3 KiB
TypeScript
60 lines
1.3 KiB
TypeScript
import path from "path"
|
|
import { writeHeapSnapshot } from "node:v8"
|
|
import { Flag } from "@opencode-ai/core/flag/flag"
|
|
import { Global } from "@/global"
|
|
import { Log } from "@/util"
|
|
|
|
const log = Log.create({ service: "heap" })
|
|
const MINUTE = 60_000
|
|
const LIMIT = 2 * 1024 * 1024 * 1024
|
|
|
|
let timer: Timer | undefined
|
|
let lock = false
|
|
let armed = true
|
|
|
|
export function start() {
|
|
if (!Flag.OPENCODE_AUTO_HEAP_SNAPSHOT) return
|
|
if (timer) return
|
|
|
|
const run = async () => {
|
|
if (lock) return
|
|
|
|
const stat = process.memoryUsage()
|
|
if (stat.rss <= LIMIT) {
|
|
armed = true
|
|
return
|
|
}
|
|
if (!armed) return
|
|
|
|
lock = true
|
|
armed = false
|
|
const file = path.join(
|
|
Global.Path.log,
|
|
`heap-${process.pid}-${new Date().toISOString().replace(/[:.]/g, "")}.heapsnapshot`,
|
|
)
|
|
log.warn("heap usage exceeded limit", {
|
|
rss: stat.rss,
|
|
heap: stat.heapUsed,
|
|
file,
|
|
})
|
|
|
|
await Promise.resolve()
|
|
.then(() => writeHeapSnapshot(file))
|
|
.catch((err) => {
|
|
log.error("failed to write heap snapshot", {
|
|
error: err instanceof Error ? err.message : String(err),
|
|
file,
|
|
})
|
|
})
|
|
|
|
lock = false
|
|
}
|
|
|
|
timer = setInterval(() => {
|
|
void run()
|
|
}, MINUTE)
|
|
timer.unref?.()
|
|
}
|
|
|
|
export * as Heap from "./heap"
|