From 21eba1f5dc29efd18a06d70dcfa3fb930c545190 Mon Sep 17 00:00:00 2001 From: lyon Date: Fri, 19 Jun 2026 15:17:09 +0800 Subject: [PATCH] fix: zero caught-up projection event lag metrics --- internal/cloud/backend-performance.test.ts | 7 ++++++- internal/cloud/backend-performance.ts | 4 +++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/internal/cloud/backend-performance.test.ts b/internal/cloud/backend-performance.test.ts index 26cba64f..8a38b2c1 100644 --- a/internal/cloud/backend-performance.test.ts +++ b/internal/cloud/backend-performance.test.ts @@ -225,7 +225,7 @@ test("backend performance reports zero projection lag for caught-up terminal tra const store = createBackendPerformanceStore({ env: { POD_NAMESPACE: "hwlab-v03", HWLAB_GITOPS_TARGET: "v03", HWLAB_RUNTIME_LANE: "v03", HWLAB_CODE_AGENT_AGENTRUN_PROVIDER_ID: "D601" } }); store.recordWorkbenchProjection({ - sourceLatestSeq: 501, + sourceLatestSeq: 601, lastProjectedSeq: 501, sourceLatestEventAt: "2026-06-19T03:00:00.000Z", projectedLatestEventAt: "2026-06-19T02:00:00.000Z", @@ -238,10 +238,15 @@ test("backend performance reports zero projection lag for caught-up terminal tra }); const text = store.metricsText(); + const lagEventsSumLine = text.split("\n").find((line) => line.startsWith("hwlab_workbench_projection_lag_events_sum") && line.includes('projection_status="caught_up"')); + const lagEventsBucketLine = text.split("\n").find((line) => line.startsWith("hwlab_workbench_projection_lag_events_bucket") && line.includes('projection_status="caught_up"') && line.includes('le="0"')); const lagSumLine = text.split("\n").find((line) => line.startsWith("hwlab_workbench_projection_lag_seconds_sum") && line.includes('projection_status="caught_up"')); const lagBucketLine = text.split("\n").find((line) => line.startsWith("hwlab_workbench_projection_lag_seconds_bucket") && line.includes('projection_status="caught_up"') && line.includes('le="0.05"')); const stuckLine = text.split("\n").find((line) => line.startsWith("hwlab_workbench_projection_stuck_traces") && line.includes('projection_status="caught_up"')); const terminalDelayBucketLine = text.split("\n").find((line) => line.startsWith("hwlab_workbench_terminal_projection_delay_seconds_bucket") && line.includes('projection_status="caught_up"') && line.includes('le="0.05"')); + assert.ok(lagEventsSumLine); + assert.match(lagEventsSumLine, / 0\.000000$/u); + assert.ok(lagEventsBucketLine?.endsWith(" 1")); assert.ok(lagSumLine); assert.match(lagSumLine, / 0\.000000$/u); assert.ok(lagBucketLine?.endsWith(" 1")); diff --git a/internal/cloud/backend-performance.ts b/internal/cloud/backend-performance.ts index b2c23282..26fa3af1 100644 --- a/internal/cloud/backend-performance.ts +++ b/internal/cloud/backend-performance.ts @@ -239,7 +239,9 @@ export function createBackendPerformanceStore(options: BackendPerformanceStoreOp const sourceSeq = finiteNonNegativeNumber(input.sourceLatestSeq); const projectedSeq = finiteNonNegativeNumber(input.lastProjectedSeq); if (sourceSeq !== null && projectedSeq !== null) { - const lagEvents = Math.max(0, Math.floor(sourceSeq - projectedSeq)); + const lagEvents = isTerminalProjectionStatus(labels.projection_status) + ? 0 + : Math.max(0, Math.floor(sourceSeq - projectedSeq)); if (!recordHistogram(projectionLagEventsSeries, labels, lagEvents, PROJECTION_LAG_EVENT_BUCKETS, maxSeries)) incrementDropped("projection_lag_events_series_limit"); setGauge(projectionStuckGaugeSeries, labels, lagEvents > 0 && labels.projection_status !== "caught_up" ? 1 : 0, maxSeries) || incrementDropped("projection_stuck_series_limit"); }