Interesting approach to tackling the 0.00 issue with a layered fallback system and clear UX cues. How do you see this method adapting when dealing with real-time crypto data that changes multiple times per second?
Thanks Muzzamil—totally agree: crypto ticks can change many times per second.
Here’s a simple pattern that scales without going HFT and is easy to copy:
Ingest (fast)
{sym, price, ts, src, seq} and store last-known-good (LKG).Coalesce (edge, 100–250 ms frames)
frameMs pick the freshest tick per symbol from the buffer.rotateMs (e.g., 1 s) → rotate provider.staleMs (e.g., 2 s) → serve LKG with stale:true.Deliver (human-speed)
stale:true.This keeps ingestion real-time, but the UI calm and trustworthy.
// constants you can tune per market
const frameMs = 200; // coalesce window (5 Hz)
const rotateMs = 1000; // try next provider if no fresh tick in 1s
const staleMs = 2000; // mark stale after 2s without a tick
type Tick = { sym: string; price: number; ts: number; src: 'p1'|'p2'|'p3'; seq: number };
const buf = new Map<string, Tick>(); // newest per sym during frame
const lkg = new Map<string, Tick>(); // last-known-good
// ingest from multiple WS feeds (pseudo)
function onProviderTick(t: Tick) {
if (!Number.isFinite(t.price)) return;
const prev = buf.get(t.sym);
if (!prev || t.ts > prev.ts) buf.set(t.sym, t); // keep latest in frame
}
// coalesce + provider rotation + stale logic
setInterval(async () => {
const now = Date.now();
for (const [sym, latest] of buf) {
const lastGood = lkg.get(sym);
const age = now - latest.ts;
let out: Tick & { stale: boolean } =
age <= staleMs ? { ...latest, stale: false }
: { ...(lastGood ?? latest), stale: true };
// rotate if no fresh tick recently (edge-side policy)
if (age > rotateMs) rotateProvider(sym); // implement round-robin/health check
lkg.set(sym, { sym: out.sym, price: out.price, ts: out.ts, src: out.src, seq: out.seq });
sendToClients(sym, out); // SSE/WS push to all subscribers
buf.delete(sym);
}
}, frameMs);
// HTTP fallback if WS is down
async function httpPoll(sym: string) {
try {
const r = await fetch(`${P1}/q?symbol=${sym}`, { signal: Abort(1400) });
if (r.ok) onProviderTick({ ...(await r.json()), src: 'p1', seq: inc(sym) });
} catch { /* ignore, coalesce loop handles stale + LKG */ }
}
Client side: render updates, and when stale:true, show “Last update 2.3 s • p2” (tooltip: “provider fallback active”). Never render 0.00.
stale:true beats silently wrong values.frameMs/rotateMs/staleMs.If you want, I can post a tiny repo with this coalescer + SSE server so folks can fork and plug in their providers.