226 lines · 6.9 KB · TypeScript
RawDownload
import {  HostProcessArchitecture,  HostProcessEnvironment,  HostProcessPlatform,} from "@t3tools/shared/hostProcess";import * as Context from "effect/Context";import * as Effect from "effect/Effect";import * as FileSystem from "effect/FileSystem";import * as Layer from "effect/Layer";import * as Option from "effect/Option";import * as Path from "effect/Path";import * as Schema from "effect/Schema"; import { ServerConfig } from "../config.ts"; export class ResourceMonitorBinaryUnsupported extends Schema.TaggedError<ResourceMonitorBinaryUnsupported>()(  "ResourceMonitorBinaryUnsupported",  {    platform: Schema.String,    architecture: Schema.String,  },) {  override get message(): string {    return `Resource monitoring is unsupported on ${this.platform}/${this.architecture}.`;  }} export class ResourceMonitorBinaryNotFound extends Schema.TaggedError<ResourceMonitorBinaryNotFound>()(  "ResourceMonitorBinaryNotFound",  {    platform: Schema.String,    architecture: Schema.String,    candidates: Schema.Array(Schema.String),  },) {  override get message(): string {    return `Resource monitor binary was not found for ${this.platform}/${this.architecture}.`;  }} export class ResourceMonitorBinaryNotExecutable extends Schema.TaggedError<ResourceMonitorBinaryNotExecutable>()(  "ResourceMonitorBinaryNotExecutable",  {    path: Schema.String,    mode: Schema.Number,  },) {  override get message(): string {    return `Resource monitor binary at '${this.path}' is not executable.`;  }} export type ResourceMonitorBinaryError =  | ResourceMonitorBinaryUnsupported  | ResourceMonitorBinaryNotFound  | ResourceMonitorBinaryNotExecutable; export class ResourceMonitorBinary extends Context.Service<  ResourceMonitorBinary,  {    readonly resolve: Effect.Effect<string, ResourceMonitorBinaryError>;  }>()("t3/resourceTelemetry/ResourceMonitorBinary") {} function binaryName(platform: NodeJS.Platform): string {  return platform === "win32" ? "t3-resource-monitor.exe" : "t3-resource-monitor";} export type ResourceMonitorLinuxLibc = "gnu" | "musl"; function detectResourceMonitorLinuxLibc(): ResourceMonitorLinuxLibc {  try {    const report = process.report?.getReport() as      | {          readonly header?: {            readonly glibcVersionRuntime?: unknown;          };        }      | undefined;    return typeof report?.header?.glibcVersionRuntime === "string" ? "gnu" : "musl";  } catch {    return "musl";  }} export const ResourceMonitorHostLinuxLibc = Context.Reference<ResourceMonitorLinuxLibc>(  "t3/resourceTelemetry/ResourceMonitorHostLinuxLibc",  {    defaultValue: detectResourceMonitorLinuxLibc,  },); function resourceMonitorPlatformKey(  platform: NodeJS.Platform,  architecture: NodeJS.Architecture,): string | undefined {  if (    (platform !== "darwin" && platform !== "linux" && platform !== "win32") ||    (architecture !== "arm64" && architecture !== "x64")  ) {    return undefined;  }  return `${platform}-${architecture}`;} function resourceMonitorRustTarget(  platform: NodeJS.Platform,  architecture: NodeJS.Architecture,  linuxLibc?: ResourceMonitorLinuxLibc,): string | undefined {  if (platform === "darwin") {    return architecture === "arm64"      ? "aarch64-apple-darwin"      : architecture === "x64"        ? "x86_64-apple-darwin"        : undefined;  }  if (platform === "linux") {    if (linuxLibc !== "gnu") {      return undefined;    }    return architecture === "arm64"      ? "aarch64-unknown-linux-gnu"      : architecture === "x64"        ? "x86_64-unknown-linux-gnu"        : undefined;  }  if (platform === "win32") {    return architecture === "arm64"      ? "aarch64-pc-windows-msvc"      : architecture === "x64"        ? "x86_64-pc-windows-msvc"        : undefined;  }  return undefined;} export const make = Effect.fn("resourceTelemetry.resourceMonitorBinary.make")(function* () {  const config = yield* ServerConfig;  const fileSystem = yield* FileSystem.FileSystem;  const path = yield* Path.Path;  const platform = yield* HostProcessPlatform;  const architecture = yield* HostProcessArchitecture;  const environment = yield* HostProcessEnvironment;  const linuxLibc = platform === "linux" ? yield* ResourceMonitorHostLinuxLibc : undefined;  const executableName = binaryName(platform);  const platformKey = resourceMonitorPlatformKey(platform, architecture);  const rustTarget = resourceMonitorRustTarget(platform, architecture, linuxLibc);  const overrideCandidates = [    environment.T3CODE_RESOURCE_MONITOR_PATH,    config.resourceMonitorPath,  ].filter((candidate): candidate is string => Boolean(candidate));  const bundledCandidates =    platformKey === undefined || rustTarget === undefined      ? []      : [          path.resolve(import.meta.dirname, "resource-monitor", platformKey, executableName),          path.resolve(import.meta.dirname, "resource-monitor", executableName),          path.resolve(import.meta.dirname, "../resource-monitor", executableName),          path.resolve(            import.meta.dirname,            "../../../../native/resource-monitor/target",            rustTarget,            "release",            executableName,          ),          path.resolve(            import.meta.dirname,            "../../../native/resource-monitor/target",            rustTarget,            "release",            executableName,          ),          path.resolve(            import.meta.dirname,            "../../../../native/resource-monitor/target/release",            executableName,          ),          path.resolve(            import.meta.dirname,            "../../../../native/resource-monitor/target/debug",            executableName,          ),        ];  if (overrideCandidates.length === 0 && bundledCandidates.length === 0) {    return ResourceMonitorBinary.of({      resolve: Effect.fail(        new ResourceMonitorBinaryUnsupported({          platform,          architecture,        }),      ),    });  }   const candidates = [...overrideCandidates, ...bundledCandidates];   const resolve: ResourceMonitorBinary["Service"]["resolve"] = Effect.gen(function* () {    for (const candidate of candidates) {      const exists = yield* fileSystem.exists(candidate).pipe(Effect.orElseSucceed(() => false));      if (!exists) continue;       if (platform !== "win32") {        const stat = yield* fileSystem.stat(candidate).pipe(Effect.option);        if (Option.isSome(stat) && (stat.value.mode & 0o111) === 0) {          return yield* new ResourceMonitorBinaryNotExecutable({            path: candidate,            mode: stat.value.mode,          });        }      }       return candidate;    }     return yield* new ResourceMonitorBinaryNotFound({      platform,      architecture,      candidates,    });  });   return ResourceMonitorBinary.of({ resolve });}); export const layer = Layer.effect(ResourceMonitorBinary, make());