Phase 1: data pipeline (Postgres+Redis with in-memory fallback, mock telemetry publisher, WebSocket fan-out, hub /debug page)
CI / Lint, typecheck, test, build (pull_request) Failing after 10s
CI / Lint, typecheck, test, build (pull_request) Failing after 10s
- packages/db: postgres.js + ioredis wrapper, StateStore interface with InMemory + Postgres implementations, schema migration runner - apps/api: refactored to use @kerbal-rt/db; live WebSocket hub subscribes to store changes and broadcasts to all clients - apps/tools/mock-telemetry: Node script that generates realistic KSP state and POSTs to /api/v1/ingest at 1Hz (uses same keplerian math as the live-map renderer) - apps/hub: new /debug page that connects to /api/v1/live and shows the live state - ksp/README.md: documents Phase 1c (real kRPC bridge) and the two implementation options - Tests: 17 total (5 kepler math, 5 db store, 5 API health/state, 2 API WebSocket fan-out) End-to-end verified: mock publisher → API → hub /debug page, 11 snapshots/5s over WebSocket, vessels advancing in mean anomaly.
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
* Redis connection wrapper. Provides one client for normal commands
|
||||
* and a separate one for pub/sub (Redis requires dedicated connections
|
||||
* for subscribe mode).
|
||||
*/
|
||||
import Redis from 'ioredis';
|
||||
|
||||
export interface RedisPair {
|
||||
/** For GET/SET/PUBLISH etc. */
|
||||
client: Redis;
|
||||
/** For SUBSCRIBE only — must not be used for other commands. */
|
||||
subscriber: Redis;
|
||||
close(): Promise<void>;
|
||||
}
|
||||
|
||||
export function createRedis(url: string): RedisPair {
|
||||
const client = new Redis(url, {
|
||||
lazyConnect: false,
|
||||
maxRetriesPerRequest: 3,
|
||||
enableReadyCheck: true,
|
||||
});
|
||||
const subscriber = new Redis(url, {
|
||||
lazyConnect: false,
|
||||
maxRetriesPerRequest: null, // subscribers reconnect forever
|
||||
});
|
||||
return {
|
||||
client,
|
||||
subscriber,
|
||||
async close() {
|
||||
await Promise.all([client.quit().catch(() => {}), subscriber.quit().catch(() => {})]);
|
||||
},
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user