46 lines
1.5 KiB
TypeScript
46 lines
1.5 KiB
TypeScript
export * as CpuProfile from "./cpu-profile"
|
|
|
|
import { Effect, FileSystem } from "effect"
|
|
import { Session } from "node:inspector"
|
|
import path from "node:path"
|
|
|
|
export function run<A, E, R>(file: string, effect: Effect.Effect<A, E, R>) {
|
|
const target = path.resolve(file)
|
|
return Effect.acquireUseRelease(
|
|
Effect.gen(function* () {
|
|
const fs = yield* FileSystem.FileSystem
|
|
yield* fs.makeDirectory(path.dirname(target), { recursive: true })
|
|
const session = new Session()
|
|
session.connect()
|
|
yield* command(session, "Profiler.enable")
|
|
yield* command(session, "Profiler.start")
|
|
yield* Effect.logInfo("CPU profile started", { path: target })
|
|
return session
|
|
}),
|
|
() => effect,
|
|
(session) =>
|
|
Effect.tryPromise(
|
|
() =>
|
|
new Promise<void>((resolve, reject) => {
|
|
session.post("Profiler.stop", (error, result) => {
|
|
session.disconnect()
|
|
if (error) return reject(error)
|
|
Bun.write(target, JSON.stringify(result.profile)).then(() => resolve(), reject)
|
|
})
|
|
}),
|
|
).pipe(
|
|
Effect.andThen(Effect.logInfo("CPU profile written", { path: target })),
|
|
Effect.catchCause((cause) => Effect.logError("Failed to write CPU profile", { path: target, cause })),
|
|
),
|
|
)
|
|
}
|
|
|
|
function command(session: Session, method: "Profiler.enable" | "Profiler.start") {
|
|
return Effect.tryPromise(
|
|
() =>
|
|
new Promise<void>((resolve, reject) => {
|
|
session.post(method, (error) => (error ? reject(error) : resolve()))
|
|
}),
|
|
)
|
|
}
|