mirror of
https://github.com/anomalyco/opencode.git
synced 2026-08-15 17:08:21 -04:00
fix(util): defer module-scope randomness, I/O, and import.meta paths
This commit is contained in:
@@ -7,13 +7,15 @@ import Config from "@npmcli/config"
|
||||
import { definitions, flatten, nerfDarts, shorthands } from "@npmcli/config/lib/definitions/index.js"
|
||||
import { Effect } from "effect"
|
||||
|
||||
const npmPath = fileURLToPath(new URL("..", import.meta.url))
|
||||
// Lazy: on workerd import.meta.url is undefined and constructing a URL from it
|
||||
// at module scope fails startup validation; npm config is never used there.
|
||||
const npmPath = () => fileURLToPath(new URL("..", import.meta.url))
|
||||
|
||||
export const load = (dir: string) =>
|
||||
Effect.tryPromise({
|
||||
try: async () => {
|
||||
const config = new Config({
|
||||
npmPath,
|
||||
npmPath: npmPath(),
|
||||
cwd: dir,
|
||||
env: { ...process.env },
|
||||
argv: [process.execPath, process.execPath, "--prefix", dir],
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
export * as Observability from "./observability.js"
|
||||
|
||||
import { NodeFileSystem } from "@effect/platform-node"
|
||||
import * as NodeFileSystem from "@effect/platform-node/NodeFileSystem"
|
||||
import { LayerNode } from "./effect/layer-node.js"
|
||||
import { Effect, Layer, Logger, References, Schema } from "effect"
|
||||
import { FetchHttpClient } from "effect/unstable/http"
|
||||
@@ -50,4 +50,10 @@ export function layer(
|
||||
).pipe(Layer.catchCause(() => local))
|
||||
}
|
||||
|
||||
export const node = LayerNode.make({ name: "observability", layer: layer(), deps: [] })
|
||||
// Layer.suspend: constructing the loggers eagerly at module scope performs
|
||||
// I/O (file logger, run id) that workerd forbids in global scope.
|
||||
export const node = LayerNode.make({
|
||||
name: "observability",
|
||||
layer: Layer.suspend(() => layer()),
|
||||
deps: [],
|
||||
})
|
||||
|
||||
@@ -3,7 +3,7 @@ import path from "path"
|
||||
import { Global } from "../global.js"
|
||||
import { runID } from "./shared.js"
|
||||
|
||||
function formatter(id: string = runID) {
|
||||
function formatter(id: string = runID()) {
|
||||
return Logger.map(Logger.formatStructured, (output) => {
|
||||
const messages = Array.isArray(output.message) ? output.message : [output.message]
|
||||
return [
|
||||
@@ -51,7 +51,7 @@ export function file(local = true, channel = "local") {
|
||||
return path.join(Global.Path.log, `opencode-${channel.replace(/[^a-zA-Z0-9._-]/g, "-")}.log`)
|
||||
}
|
||||
|
||||
export function fileLogger(target = file(), id: string = runID) {
|
||||
export function fileLogger(target = file(), id: string = runID()) {
|
||||
// Do not set batchWindow to 0; it causes high idle CPU usage.
|
||||
return Effect.gen(function* () {
|
||||
const fs = yield* FileSystem.FileSystem
|
||||
|
||||
@@ -54,8 +54,8 @@ export function resource(app: App = { client: "opencode", version: "unknown", ch
|
||||
...resourceAttributes(),
|
||||
"deployment.environment.name": app.channel,
|
||||
"opencode.client": app.client,
|
||||
"opencode.run": runID,
|
||||
"service.instance.id": runID,
|
||||
"opencode.run": runID(),
|
||||
"service.instance.id": runID(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1 +1,8 @@
|
||||
export const runID = crypto.randomUUID().slice(0, 8)
|
||||
// Lazy: workerd forbids generating random values in global scope, so the id
|
||||
// materializes on first call (inside a handler) and stays stable afterwards.
|
||||
let generated: string | undefined
|
||||
|
||||
export function runID(): string {
|
||||
generated ??= crypto.randomUUID().slice(0, 8)
|
||||
return generated
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user