Methods

(static) apiPipelineAbandon(record) → {void}

Releases a record whose answer this run will not read (the budget ran out, or the run ended early), and marks its request abandoned so the pool may skip it if it is still queued (apiPool.bs, "Skipping a request nobody is waiting for").

Parameters:
NameTypeDescription
recorddynamic
Returns:
Type: 
void

(static) apiPipelineAddPending(pipe, requestId, index, node) → {void}

Records a submitted request as in flight.

Parameters:
NameTypeDescription
pipeobject
requestIdstring
indexinteger
nodedynamic
Returns:
Type: 
void

(static) apiPipelineAdvance(pipe) → {dynamic}

The body of apiPipelineNext, between the budget resume and pause. Split out so every return below is charged the same way without repeating the pause at each.

Parameters:
NameTypeDescription
pipeobject
Returns:
Type: 
dynamic

(static) apiPipelineBegin(entries, budgetMsopt) → {dynamic}

Starts a pipeline run over entries.

entries is empty / invalid

Parameters:
NameTypeAttributesDefaultDescription
entriesdynamic

array of AAs, each { requestId: string, req: AA, ...payload }

budgetMsinteger<optional>
timeouts.PIPELINE_RUN_MS

whole-run budget in ms; defaults to timeouts.PIPELINE_RUN_MS

Returns:

an opaque pipe state AA to pass to apiPipelineNext(), or invalid if

Type: 
dynamic

(static) apiPipelineBudgetPause(pipe, nowMs) → {void}

Stops charging the budget: a result is being handed back to the caller.

Parameters:
NameTypeDescription
pipeobject
nowMsinteger
Returns:
Type: 
void

(static) apiPipelineBudgetResume(pipe, nowMs) → {void}

Starts charging the budget again, crediting the time the caller held the result. A no-op on the first call, before anything has been handed back.

Parameters:
NameTypeDescription
pipeobject
nowMsinteger
Returns:
Type: 
void

(static) apiPipelineBudgetSpent(budgetMs, elapsedMs) → {boolean}

Has the whole-run budget been used up?

Small enough to inline, but named and separate on purpose: the clock lives in the shell and is therefore untestable, whereas this predicate is pinned by unit tests, including that the budget counts as spent at zero rather than one tick later. Any second budget check added later must call this rather than re-derive the comparison; two hand-written checks disagreeing is precisely the bug that a post-completion refill introduced here once.

Parameters:
NameTypeDescription
budgetMsinteger
elapsedMsinteger
Returns:
Type: 
boolean

(static) apiPipelineBudgetUsedMs(pipe, nowMs) → {integer}

How much of the budget the run has used at nowMs on its clock: wall time minus the time the caller has held a result.

Parameters:
NameTypeDescription
pipeobject
nowMsinteger
Returns:
Type: 
integer

(static) apiPipelineClaimNext(pipe) → {dynamic}

Claims the next queued entry for submission and advances the cursor, so an entry can never be submitted twice.

Parameters:
NameTypeDescription
pipeobject
Returns:

an AA { entry, index, node: invalid }, or invalid when the queue is empty

Type: 
dynamic

(static) apiPipelineDrainOne(pipe) → {dynamic}

Yields the next entry that will never be delivered, once the budget is spent: in-flight requests first (lowest entry index first), then unsubmitted ones in entry order. Returns invalid when nothing is left.

Parameters:
NameTypeDescription
pipeobject
Returns:
Type: 
dynamic

(static) apiPipelineEnd(pipe) → {void}

Releases every still-in-flight request without waiting for it. Only needed by a caller that abandons the run early (breaking out of the loop before apiPipelineNext returns invalid). A run driven to exhaustion has already released everything. Idempotent; safe on a finished pipe.

A late pool response after this writes to an abandoned result node and is ignored, exactly as fetchRes's timeout path leaves its node behind. bsc-disable-next-line dead-code keep: api: the early-exit half of the pipeline lifecycle; every current orchestrator drains its run

Parameters:
NameTypeDescription
pipedynamic
Returns:
Type: 
void

(static) apiPipelineEventRequestId(msg) → {dynamic}

Recovers the requestId from an isDone event. submitApiRequest stamps it onto the request AA the result node carries; the node's own id is left unset.

Parameters:
NameTypeDescription
msgobject
Returns:
Type: 
dynamic

(static) apiPipelineHasQueued(pipe) → {boolean}

Are there entries that have not been submitted yet?

Parameters:
NameTypeDescription
pipeobject
Returns:
Type: 
boolean

(static) apiPipelineIsDone(pipe) → {boolean}

A run is finished only when nothing is queued and nothing is in flight. An empty queue with requests still outstanding is not done.

Parameters:
NameTypeDescription
pipeobject
Returns:
Type: 
boolean

(static) apiPipelineNext(pipe) → {dynamic}

Advances the pipeline: tops the pool up to its slot count, then blocks until one request completes.

invalid if that entry never got an answer), or invalid when the run is exhausted (every entry has been yielded exactly once).

Parameters:
NameTypeDescription
pipedynamic

the AA from apiPipelineBegin()

Returns:

an AA { entry, res } for one entry (res is the pool response AA, or

Type: 
dynamic

(static) apiPipelineRefill(pipe) → {void}

Submits queued entries until the pool is full or the queue is empty.

Best-effort by contract: an entry it cannot submit is put BACK on the queue (the claim is reverted) rather than consumed. That keeps the undeliverable path in one place: apiPipelineNext's top-up, which yields the entry to the caller with res = invalid. Without the revert, an entry claimed here and dropped would never be yielded at all, breaking the exactly-once guarantee.

Parameters:
NameTypeDescription
pipedynamic
Returns:
Type: 
void

(static) apiPipelineRelease(record) → {void}

Drops the pool observer for a finished record. Records claimed but never submitted carry no node, so this is a no-op for them.

Parameters:
NameTypeDescription
recorddynamic
Returns:
Type: 
void

(static) apiPipelineSlotsFree(pipe) → {integer}

How many more requests may be put in flight right now.

Parameters:
NameTypeDescription
pipeobject
Returns:
Type: 
integer

(static) apiPipelineTake(pipe, requestId) → {dynamic}

Removes and returns the in-flight record for requestId, freeing its slot. Idempotent by design: an unknown or already-taken id returns invalid, so a duplicate or late event is a no-op rather than a double delivery.

Parameters:
NameTypeDescription
pipeobject
requestIddynamic
Returns:
Type: 
dynamic

(static) apiPipelineWaitMs(remainingMs) → {integer}

How long to block on one wait: never past the run budget, never longer than a single request's own deadline.

Parameters:
NameTypeDescription
remainingMsinteger
Returns:
Type: 
integer