Skip to content

Commit 3f8ba0a

Browse files
MariefayTrigger.dev RepoOps
authored andcommitted
feat(webapp): incremental live tail for the run trace view
Live runs in the run trace view now update incrementally. Instead of reloading the whole trace on every update, the page fetches only the rows written since its last read and merges them into the tree it already has, so large live traces keep updating without re-downloading everything. Progressive trace loading now always uses this live tail. Mono-RevId: 8cc2387d2af102abc3a17d23b3ad1e0a2846aca5
1 parent 739b193 commit 3f8ba0a

22 files changed

Lines changed: 1906 additions & 70 deletions

‎.env.schema‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ RUN_REPLICATION_CLICKHOUSE_URL=${CLICKHOUSE_URL}
4141
RUN_REPLICATION_ENABLED=1
4242
# LOGS_SEARCH_PROJECTOR_ENABLED=1
4343
# LOGS_SEARCH_PROJECTOR_PREVIEW_ENABLED=1
44+
# Live tail for progressive trace loading; "1" turns it on, anything else turns it off.
45+
# INCREMENTAL_LIVE_TAIL_ENABLED=0
4446
# Store task run spans/traces in ClickHouse so the dashboard trace view is
4547
# populated in local dev. The local stack is ClickHouse-backed (see above), so
4648
# leaving this unset falls back to the "postgres" store and dev run traces show

‎apps/webapp/app/env.server.ts‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1116,6 +1116,8 @@ const EnvironmentSchema = z
11161116
EVENT_LOOP_UTILIZATION_MONITOR_ENABLED: z.string().default("1"),
11171117
MAXIMUM_LIVE_RELOADING_EVENTS: z.coerce.number().int().default(1000),
11181118
MAXIMUM_TRACE_SUMMARY_VIEW_COUNT: z.coerce.number().int().default(25_000),
1119+
// Live tail for progressive trace loading; "1" on, anything else off.
1120+
INCREMENTAL_LIVE_TAIL_ENABLED: z.string().default("0"),
11191121
MAXIMUM_TRACE_DETAILED_SUMMARY_VIEW_COUNT: z.coerce.number().int().default(10_000),
11201122
// Emergency circuit breaker: when set, clamps the trace summary and detailed
11211123
// summary span limits on both event store paths to this value. Unset = disabled.

‎apps/webapp/app/hooks/liveTail.ts‎

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// React-free live tail helpers.
2+
3+
// How far back each tail re-reads for late-visible rows; a full sweep runs periodically.
4+
export const LIVE_TAIL_OVERLAP_MS = 5_000;
5+
export const LIVE_TAIL_SWEEP_OVERLAP_MS = 30_000;
6+
export const LIVE_TAIL_SWEEP_INTERVAL_MS = 20_000;
7+
8+
export function tailOverlapMs(nowMs: number, lastSweepAtMs: number): number {
9+
return nowMs - lastSweepAtMs >= LIVE_TAIL_SWEEP_INTERVAL_MS
10+
? LIVE_TAIL_SWEEP_OVERLAP_MS
11+
: LIVE_TAIL_OVERLAP_MS;
12+
}
13+
14+
// Min spacing between tail reads, growing with trace size.
15+
export function tailMinIntervalMs(loadedSpans: number): number {
16+
if (loadedSpans >= 100_000) return 15_000;
17+
if (loadedSpans >= 50_000) return 5_000;
18+
if (loadedSpans >= 5_000) return 2_000;
19+
return 0;
20+
}
21+
22+
// Tail only when the server enabled it for a progressive payload.
23+
export function resolveLiveTailEnabled(
24+
progressive: { liveTailEnabled?: boolean } | null | undefined
25+
): boolean {
26+
return progressive != null && progressive.liveTailEnabled === true;
27+
}

0 commit comments

Comments
 (0)