import { fault } from '../canvas-core/values.ts'; import { createDeque } from './structures.ts'; /** Shared bounded transport capacity for writes, uploads and run reads. */ export function createNetworkGate(limit = 2) { if(!Number.isSafeInteger(limit)||limit<1)throw fault('invalid_concurrency'); let active = 0; const waiting = createDeque<{ signal: AbortSignal; grant(): void; cancelled: boolean }>(); async function enter(signal: AbortSignal) { signal.throwIfAborted(); if (active < limit) { active++; return; } await new Promise((resolve,reject) => { const item = { signal, cancelled: false, grant() { signal.removeEventListener('abort',abort);resolve(); } }; const abort = () => { item.cancelled=true;signal.removeEventListener('abort',abort);reject(signal.reason); }; signal.addEventListener('abort',abort,{once:true});waiting.push(item); }); } function release() { let item=waiting.pop();while(item?.cancelled)item=waiting.pop(); if(item)item.grant();else active--; } return Object.freeze({ async run(signal: AbortSignal, callback: () => Promise): Promise { await enter(signal); try { signal.throwIfAborted();return await callback(); } finally { release(); } } }); }