| Name | Last commit message | Updated |
|---|---|---|
| ▣.. | ||
| ▣__fixtures__ | add replay fixtures captured from prod shard 4 | 6 days ago |
| ▤index.ts | re-export TaskHandle so consumers stop deep-importing | 2 days ago |
| ▤scheduler.ts | drain microtasks before advancing the virtual clock | 3 hours ago |
| ▤queue.ts | swap linked list for a ring buffer — 3.1× on fanout bench | 4 days ago |
| ▤clock.ts | clamp drift correction to ±2ms per tick | 2 weeks ago |
| ▤replay-log.ts | write frame checksums so truncated logs fail loudly | 3 weeks ago |
| ▤scheduler.test.ts | cover the starvation case Priya found in staging | 3 hours ago |
| ▤package.json | bump to 2.9.0-rc.3 | 3 days ago |
scheduler.ts
148 lines4.2 KBTypeScript
41/** Cooperative scheduler. Never allocates inside `tick`. */ 42export class Scheduler { 43 readonly #queue = new RingQueue<Task>(4096); 44 readonly #clock: VirtualClock; 45 #epoch = 0; 46 47 // c4f19ab — drain microtasks first, otherwise a task that 48 // resolves during tick() observes tomorrow's clock. 49 async tick(budgetMs = 8): Promise<number> { 50 await this.drainMicrotasks(); 51 const deadline = this.#clock.now() + budgetMs; 52 let drained = 0; 53 54 while (this.#queue.size > 0) { 55 if (this.#clock.now() >= deadline) { 56 this.emit("budget-exhausted", { drained }); 57 break; 58 } 59 const task = this.#queue.shift()!; 60 this.run(task, this.#epoch); 61 drained++; 62 } 63 64 this.#epoch++; 65 return drained; 66 } 67}
Recent history — packages/runtime
- c4f19abiris-kovac — drain microtasks before advancing the virtual clock
- 9de0177priya-anand — cover the starvation case found in staging shard 4
- 40bb3c2tomas-erdely — swap linked list for a ring buffer (3.1× fanout)
- 1f7a55eiris-kovac — re-export TaskHandle from the package root
- 8c23d90dep-bot — bump @ferrite/codec to 2.4.1
README.md
Ferrite is the scheduling core behind Nightshift's edge platform. It runs the same code on a laptop, in CI, and on 340 points of presence — and it produces byte-identical event logs in all three.
Why determinism
If a request misbehaves in production, you shouldn't need to reproduce the weather. Ferrite records every scheduling decision into a replay log; ferrite inspect --replay reconstructs the exact interleaving locally.
Install
npm i @ferrite/runtime@2.9.0-rc.3
Design constraints
- No allocations inside
tick()— the ring buffer is sized at construction. - Wall-clock reads are forbidden below the
VirtualClockboundary. - Every emitted event carries an epoch, so logs sort without timestamps.
- Public API changes require a fixture diff in
__fixtures__.