mattrguerra/meridian-orders-mcpmainPrivate on GitHub, published here in full

ratelimit.mjs

Language JavaScript1.5 KB31 lines

mcp-server/verify/ratelimit.mjs

  1. // Offline verification of the rate limiter. NO network.
  2. // Run after `npm run build`: node verify/ratelimit.mjs
  3. import { reserveSlot, InMemoryRateLimiter, PLINTH_RATE_LIMIT } from "../dist/lib/rateLimit.js";
  4. let pass = 0, fail = 0;
  5. const eq = (desc, got, want) => {
  6. const ok = JSON.stringify(got) === JSON.stringify(want);
  7. console.log(`${ok ? "PASS" : "FAIL"} ${desc} got=${JSON.stringify(got)}${ok ? "" : ` want=${JSON.stringify(want)}`}`);
  8. ok ? pass++ : fail++;
  9. };
  10. eq("PLINTH_RATE_LIMIT = 9 per 10000ms", PLINTH_RATE_LIMIT, { max: 9, windowMs: 10000 });
  11. let slots = [];
  12. const delays = [];
  13. for (let i = 0; i < 5; i++) { const r = reserveSlot(slots, 0, 2, 1000); delays.push(r.delayMs); slots = r.slots; }
  14. eq("burst of 5 (max=2/1000ms) spreads", delays, [0, 0, 1000, 1000, 2000]);
  15. eq("slot array bounded to max", slots.length <= 2, true);
  16. eq("aged-out slots don't delay", reserveSlot([0, 0], 100000, 2, 1000).delayMs, 0);
  17. const lim = new InMemoryRateLimiter(2, 300);
  18. const t0 = Date.now();
  19. const elapsed = [];
  20. for (let i = 0; i < 5; i++) { await lim.acquire(); elapsed.push(Date.now() - t0); }
  21. console.log(" completion times (ms):", elapsed);
  22. eq("first 2 immediate", elapsed[0] < 100 && elapsed[1] < 100, true);
  23. eq("3rd & 4th delayed ~1 window", elapsed[2] >= 250 && elapsed[3] >= 250, true);
  24. eq("5th delayed ~2 windows", elapsed[4] >= 550, true);
  25. console.log(`\n${fail === 0 ? "ALL PASS" : "FAILURES"} - ${pass} passed, ${fail} failed`);
  26. process.exit(fail === 0 ? 0 : 1);