specificClass.js 319 → 311 lines. Removed inline _dispatchInFlight +
_delayedCall + finally block. handleInput is now a 1-line delegate
to DemandDispatcher.fireAndWait({source, demand, ...}).
turnOffAllMachines calls _demandDispatcher.cancelPending().
DemandDispatcher 39 → 53 lines. One integration test rewritten to
use the new sentinel-resolution semantics. 77/77 tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
54 lines
1.7 KiB
JavaScript
54 lines
1.7 KiB
JavaScript
'use strict';
|
|
|
|
const { LatestWinsGate } = require('generalFunctions');
|
|
|
|
// Thin wrapper around LatestWinsGate for the MGC demand path. Replaces
|
|
// the original `_dispatchInFlight` + `_delayedCall` pair in
|
|
// specificClass.handleInput: a new demand arriving while a dispatch is
|
|
// in flight overwrites any pending one, so the latest value always wins
|
|
// and intermediates are dropped silently.
|
|
|
|
class DemandDispatcher {
|
|
constructor(ctx = {}, runFn) {
|
|
if (typeof runFn !== 'function') {
|
|
throw new TypeError('DemandDispatcher requires a runFn');
|
|
}
|
|
this.ctx = ctx;
|
|
this.logger = ctx.logger || null;
|
|
this._runFn = runFn;
|
|
this._gate = new LatestWinsGate(
|
|
async (demand) => this._runFn(demand, this.ctx),
|
|
{ logger: this.logger },
|
|
);
|
|
}
|
|
|
|
fire(demand) {
|
|
this._gate.fire(demand);
|
|
}
|
|
|
|
// Returns a promise that resolves when THIS demand's dispatch settles.
|
|
// If superseded by a later fireAndWait while parked, the promise
|
|
// resolves with the LatestWinsGate SUPERSEDED sentinel
|
|
// ({ superseded: true }) — callers can branch on it without try/catch.
|
|
fireAndWait(demand) {
|
|
return this._gate.fireAndWait(demand);
|
|
}
|
|
|
|
drain() {
|
|
return this._gate.drain();
|
|
}
|
|
|
|
// Cancels any parked pending value so it cannot run. The currently
|
|
// in-flight dispatch (if any) still runs to completion. A parked
|
|
// fireAndWait promise resolves with the SUPERSEDED sentinel.
|
|
cancelPending() {
|
|
if (this._gate._pending) this._gate._supersedePending();
|
|
}
|
|
|
|
get inFlight() {
|
|
return this._gate.size > 0;
|
|
}
|
|
}
|
|
|
|
module.exports = DemandDispatcher;
|