feat(electrobun): multi-machine relay + OTEL telemetry
Multi-machine relay: - relay-client.ts: WebSocket client for agor-relay with token auth, exponential backoff (1s-30s), TCP probe, heartbeat (15s ping) - machines-store.svelte.ts: remote machine state tracking - RemoteMachinesSettings.svelte: machine list, add/connect/disconnect UI - 7 RPC types (remote.connect/disconnect/list/send/status + events) Telemetry: - telemetry.ts: OTEL spans + OTLP/HTTP export to Tempo, controlled by AGOR_OTLP_ENDPOINT env var - telemetry-bridge.ts: tel.info/warn/error frontend convenience API - telemetry.log RPC for frontend→Bun tracing
This commit is contained in:
parent
ec30c69c3e
commit
88206205fe
11 changed files with 1458 additions and 15 deletions
89
ui-electrobun/src/mainview/machines-store.svelte.ts
Normal file
89
ui-electrobun/src/mainview/machines-store.svelte.ts
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
/**
|
||||
* Svelte 5 rune store for remote machine state.
|
||||
*
|
||||
* Tracks connected machines, their status, and latency.
|
||||
* Driven by remote.statusChange and remote.event messages from the Bun process.
|
||||
*/
|
||||
|
||||
// ── Types ──────────────────────────────────────────────────────────────────
|
||||
|
||||
export type MachineStatus = "connecting" | "connected" | "disconnected" | "error";
|
||||
|
||||
export interface RemoteMachine {
|
||||
machineId: string;
|
||||
label: string;
|
||||
url: string;
|
||||
status: MachineStatus;
|
||||
latencyMs: number | null;
|
||||
error?: string;
|
||||
}
|
||||
|
||||
// ── Store ──────────────────────────────────────────────────────────────────
|
||||
|
||||
let machines = $state<RemoteMachine[]>([]);
|
||||
|
||||
/** Add a machine to the tracked list. */
|
||||
export function addMachine(
|
||||
machineId: string,
|
||||
url: string,
|
||||
label?: string,
|
||||
): void {
|
||||
// Prevent duplicates
|
||||
if (machines.some((m) => m.machineId === machineId)) return;
|
||||
|
||||
machines = [
|
||||
...machines,
|
||||
{
|
||||
machineId,
|
||||
label: label ?? url,
|
||||
url,
|
||||
status: "connecting",
|
||||
latencyMs: null,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
/** Remove a machine from tracking. */
|
||||
export function removeMachine(machineId: string): void {
|
||||
machines = machines.filter((m) => m.machineId !== machineId);
|
||||
}
|
||||
|
||||
/** Update the status of a tracked machine. */
|
||||
export function updateMachineStatus(
|
||||
machineId: string,
|
||||
status: MachineStatus,
|
||||
error?: string,
|
||||
): void {
|
||||
machines = machines.map((m) =>
|
||||
m.machineId === machineId
|
||||
? { ...m, status, error: error ?? undefined }
|
||||
: m,
|
||||
);
|
||||
}
|
||||
|
||||
/** Update the measured latency for a machine. */
|
||||
export function updateMachineLatency(
|
||||
machineId: string,
|
||||
latencyMs: number,
|
||||
): void {
|
||||
machines = machines.map((m) =>
|
||||
m.machineId === machineId ? { ...m, latencyMs } : m,
|
||||
);
|
||||
}
|
||||
|
||||
/** Get all tracked machines (reactive). */
|
||||
export function getMachines(): RemoteMachine[] {
|
||||
return machines;
|
||||
}
|
||||
|
||||
/** Get a single machine by ID (reactive). */
|
||||
export function getMachineStatus(
|
||||
machineId: string,
|
||||
): RemoteMachine | undefined {
|
||||
return machines.find((m) => m.machineId === machineId);
|
||||
}
|
||||
|
||||
/** Get count of connected machines (reactive). */
|
||||
export function getConnectedCount(): number {
|
||||
return machines.filter((m) => m.status === "connected").length;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue