Stabilize tape virtualization and scoped live health

This commit is contained in:
dirtydishes 2026-05-07 01:52:20 -04:00
parent 034d24f8ac
commit e69bf295c8
11 changed files with 866 additions and 273 deletions

View file

@ -1,6 +1,7 @@
import { describe, expect, it } from "bun:test";
import type { ClickHouseClient } from "@islandflow/storage";
import {
HOT_LIVE_REDIS_KEYS,
LiveStateManager,
isLiveItemFresh,
resolveGenericLiveLimits,
@ -729,6 +730,122 @@ describe("LiveStateManager", () => {
expect(persisted).toHaveLength(1);
});
it("includes hot-channel health for options, nbbo, equities, and flow", async () => {
const manager = new LiveStateManager(makeClickHouse(), null);
const now = Date.now();
await manager.ingest("options", {
source_ts: now,
ingest_ts: now + 1,
seq: 1,
trace_id: "opt-health",
ts: now,
option_contract_id: "AAPL-2025-01-17-200-C",
price: 1,
size: 10,
exchange: "X"
});
await manager.ingest("nbbo", {
source_ts: now,
ingest_ts: now + 1,
seq: 1,
trace_id: "nbbo-health",
ts: now,
option_contract_id: "AAPL-2025-01-17-200-C",
bid: 1,
ask: 1.1,
bidSize: 10,
askSize: 10
});
await manager.ingest("equities", {
source_ts: now,
ingest_ts: now + 1,
seq: 1,
trace_id: "eq-health",
ts: now,
underlying_id: "AAPL",
price: 100,
size: 10,
exchange: "X",
offExchangeFlag: false
});
await manager.ingest("flow", {
source_ts: now,
ingest_ts: now + 1,
seq: 1,
trace_id: "flow-health",
id: "flow-health",
members: [],
features: {},
join_quality: {}
});
const health = manager.getHotChannelHealth();
expect(health.options.healthy).toBe(true);
expect(health.nbbo.healthy).toBe(true);
expect(health.equities.healthy).toBe(true);
expect(health.flow.healthy).toBe(true);
expect(health.options.freshness_age_ms).not.toBeNull();
expect(health.nbbo.freshness_age_ms).not.toBeNull();
expect(health.equities.freshness_age_ms).not.toBeNull();
expect(health.flow.freshness_age_ms).not.toBeNull();
});
it("tracks generic cache and scoped clickhouse snapshot sources separately", async () => {
const manager = new LiveStateManager(makeClickHouse(() => []), null);
const now = Date.now();
await manager.ingest("options", {
source_ts: now,
ingest_ts: now + 1,
seq: 1,
trace_id: "opt-snapshot",
ts: now,
option_contract_id: "SPY-2025-01-17-500-C",
price: 1,
size: 10,
exchange: "X"
});
await manager.getSnapshot({ channel: "options" });
await manager.getSnapshot({
channel: "options",
underlying_ids: ["QQQ"],
option_contract_id: "QQQ-2025-01-17-400-C"
});
const stats = manager.getStatsSnapshot();
expect(stats.genericCacheSnapshots).toBe(1);
expect(stats.scopedClickHouseSnapshots).toBe(1);
});
it("keeps backend channel health healthy when a scoped query is quiet", async () => {
const manager = new LiveStateManager(makeClickHouse(() => []), null);
const now = Date.now();
await manager.ingest("options", {
source_ts: now,
ingest_ts: now + 1,
seq: 1,
trace_id: "opt-global",
ts: now,
option_contract_id: "SPY-2025-01-17-500-C",
price: 1,
size: 10,
exchange: "X"
});
const quietSnapshot = await manager.getSnapshot({
channel: "options",
underlying_ids: ["QQQ"],
option_contract_id: "QQQ-2025-01-17-400-C"
});
expect(quietSnapshot.items).toEqual([]);
expect(manager.getHotChannelHealth().options.healthy).toBe(true);
expect(manager.getStatsSnapshot().freshnessAgeMsByKey[HOT_LIVE_REDIS_KEYS.options]).toBeLessThanOrEqual(50);
});
it("exposes freshness helper for feed status", () => {
expect(isLiveItemFresh("options", { ts: 1000 }, 1010)).toBe(true);
expect(isLiveItemFresh("options", { ts: 1000 }, 20_001)).toBe(false);