Bench Emitter

index.jsx 35 lines

Files · 2
1234567891011121314151617181920212223242526272829303132333435// Latency benchmark emitter. Reads kv 'bench-config'
//   { n, interval_ms, start_delay_ms }
// (seeded by tools/bench/e2e.ts), prepares a 10,000-row indexed table for
// DB-reading transforms, then emits n 'bench-out' events, each stamped with
// t0 = performance.timeOrigin + performance.now() taken just before the
// emit call. Emit-call durations are stored in kv 'emit-stats'.
const now = () => performance.timeOrigin + performance.now();
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));

async function main() {
  const loadedAt = now();
  document.body.textContent = 'bench emitter: loading';
  const cfg = (await window.lattice.kv.get('bench-config')) || { n: 0 };
  await window.lattice.db.exec('CREATE TABLE IF NOT EXISTS items (id INTEGER PRIMARY KEY, k TEXT, v TEXT)');
  await window.lattice.db.exec('CREATE INDEX IF NOT EXISTS items_k ON items (k)');
  const have = await window.lattice.db.query('SELECT count(*) AS n FROM items');
  if (have[0].n < 10000) {
    await window.lattice.db.exec(
      "INSERT INTO items (k, v) WITH RECURSIVE n(i) AS (SELECT 0 UNION ALL SELECT i + 1 FROM n WHERE i < 9999) SELECT 'key' || i, 'value' || i FROM n"
    );
  }
  await window.lattice.kv.set('clock', { loaded_at: loadedAt, skew_ms: now() - Date.now() });
  await sleep(cfg.start_delay_ms || 0);
  const durations = [];
  for (let seq = 0; seq < cfg.n; seq++) {
    const t0 = now();
    await window.lattice.events.emit('bench-out', { seq, t0 });
    durations.push(now() - t0);
    document.body.textContent = 'bench emitter: sent ' + (seq + 1) + '/' + cfg.n;
    if (seq < cfg.n - 1) await sleep(cfg.interval_ms || 100);
  }
  await window.lattice.kv.set('emit-stats', { durations, done_at: now() });
}

main().catch((e) => { document.body.textContent = 'bench emitter error: ' + e; });