fix: wire OTLP logs for diagnostics
This commit is contained in:
@@ -1,8 +1,32 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
const diagnosticMocks = vi.hoisted(() => ({
|
||||
logLaneEnqueue: vi.fn(),
|
||||
logLaneDequeue: vi.fn(),
|
||||
diag: {
|
||||
debug: vi.fn(),
|
||||
warn: vi.fn(),
|
||||
error: vi.fn(),
|
||||
},
|
||||
}));
|
||||
|
||||
vi.mock("../logging/diagnostic.js", () => ({
|
||||
logLaneEnqueue: diagnosticMocks.logLaneEnqueue,
|
||||
logLaneDequeue: diagnosticMocks.logLaneDequeue,
|
||||
diagnosticLogger: diagnosticMocks.diag,
|
||||
}));
|
||||
|
||||
import { enqueueCommand, getQueueSize } from "./command-queue.js";
|
||||
|
||||
describe("command queue", () => {
|
||||
beforeEach(() => {
|
||||
diagnosticMocks.logLaneEnqueue.mockClear();
|
||||
diagnosticMocks.logLaneDequeue.mockClear();
|
||||
diagnosticMocks.diag.debug.mockClear();
|
||||
diagnosticMocks.diag.warn.mockClear();
|
||||
diagnosticMocks.diag.error.mockClear();
|
||||
});
|
||||
|
||||
it("runs tasks one at a time in order", async () => {
|
||||
let active = 0;
|
||||
let maxActive = 0;
|
||||
@@ -29,6 +53,15 @@ describe("command queue", () => {
|
||||
expect(getQueueSize()).toBe(0);
|
||||
});
|
||||
|
||||
it("logs enqueue depth after push", async () => {
|
||||
const task = enqueueCommand(async () => {});
|
||||
|
||||
expect(diagnosticMocks.logLaneEnqueue).toHaveBeenCalledTimes(1);
|
||||
expect(diagnosticMocks.logLaneEnqueue.mock.calls[0]?.[1]).toBe(1);
|
||||
|
||||
await task;
|
||||
});
|
||||
|
||||
it("invokes onWait callback when a task waits past the threshold", async () => {
|
||||
let waited: number | null = null;
|
||||
let queuedAhead: number | null = null;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { CommandLane } from "./lanes.js";
|
||||
import { diagnosticLogger as diag, logLaneDequeue, logLaneEnqueue } from "../logging/diagnostic.js";
|
||||
|
||||
// Minimal in-process queue to serialize command executions.
|
||||
// Default lane ("main") preserves the existing behavior. Additional lanes allow
|
||||
@@ -49,16 +50,27 @@ function drainLane(lane: string) {
|
||||
const waitedMs = Date.now() - entry.enqueuedAt;
|
||||
if (waitedMs >= entry.warnAfterMs) {
|
||||
entry.onWait?.(waitedMs, state.queue.length);
|
||||
diag.warn(
|
||||
`lane wait exceeded: lane=${lane} waitedMs=${waitedMs} queueAhead=${state.queue.length}`,
|
||||
);
|
||||
}
|
||||
logLaneDequeue(lane, waitedMs, state.queue.length);
|
||||
state.active += 1;
|
||||
void (async () => {
|
||||
const startTime = Date.now();
|
||||
try {
|
||||
const result = await entry.task();
|
||||
state.active -= 1;
|
||||
diag.debug(
|
||||
`lane task done: lane=${lane} durationMs=${Date.now() - startTime} active=${state.active} queued=${state.queue.length}`,
|
||||
);
|
||||
pump();
|
||||
entry.resolve(result);
|
||||
} catch (err) {
|
||||
state.active -= 1;
|
||||
diag.error(
|
||||
`lane task error: lane=${lane} durationMs=${Date.now() - startTime} error="${String(err)}"`,
|
||||
);
|
||||
pump();
|
||||
entry.reject(err);
|
||||
}
|
||||
@@ -97,6 +109,7 @@ export function enqueueCommandInLane<T>(
|
||||
warnAfterMs,
|
||||
onWait: opts?.onWait,
|
||||
});
|
||||
logLaneEnqueue(cleaned, state.queue.length + state.active);
|
||||
drainLane(cleaned);
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user