UNPKG

@cliz/inlets

Version:
86 lines (85 loc) 2.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.FlowController = void 0; class FlowController { constructor(defaultMaxWindowSize, onBackpressure) { this.windows = new Map(); this.defaultMaxWindowSize = 1024 * 1024; if (defaultMaxWindowSize) { this.defaultMaxWindowSize = defaultMaxWindowSize; } this.onBackpressure = onBackpressure; } initializeStream(streamId, maxWindowSize) { const windowSize = maxWindowSize || this.defaultMaxWindowSize; this.windows.set(streamId, { sendWindow: 0, receiveWindow: windowSize, maxWindowSize: windowSize, }); } canSend(streamId, size) { const window = this.windows.get(streamId); if (!window) { this.initializeStream(streamId); return this.canSend(streamId, size); } return window.sendWindow + size <= window.maxWindowSize; } send(streamId, size) { if (!this.canSend(streamId, size)) { if (this.onBackpressure) { this.onBackpressure(streamId, true); } return false; } const window = this.windows.get(streamId); if (window) { window.sendWindow += size; } return true; } onAck(streamId, ackedSize) { const window = this.windows.get(streamId); if (window) { window.sendWindow = Math.max(0, window.sendWindow - ackedSize); if (window.sendWindow < window.maxWindowSize * 0.5 && this.onBackpressure) { this.onBackpressure(streamId, false); } } } receive(streamId, size) { const window = this.windows.get(streamId); if (!window) { this.initializeStream(streamId); return this.receive(streamId, size); } if (window.receiveWindow < size) { if (this.onBackpressure) { this.onBackpressure(streamId, true); } return false; } window.receiveWindow -= size; return true; } releaseReceiveWindow(streamId, size) { const window = this.windows.get(streamId); if (window) { window.receiveWindow = Math.min(window.maxWindowSize, window.receiveWindow + size); if (window.receiveWindow > window.maxWindowSize * 0.5 && this.onBackpressure) { this.onBackpressure(streamId, false); } } } getWindowState(streamId) { return this.windows.get(streamId); } removeStream(streamId) { this.windows.delete(streamId); } clear() { this.windows.clear(); } } exports.FlowController = FlowController;