UNPKG

timeline-state-resolver

Version:
77 lines 3.26 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.CommandExecutor = void 0; const _ = require("underscore"); class CommandExecutor { constructor(logger, mode, sendCommand) { this.logger = logger; this.mode = mode; this.sendCommand = sendCommand; } async executeCommands(commands, measurement) { if (commands.length === 0) return; // Sort the commands, so that the ones with the highest preliminary time are executed first. commands.sort((a, b) => (b.preliminary ?? 0) - (a.preliminary ?? 0)); const totalTime = commands[0].preliminary ?? 0; if (this.mode === 'salvo') { return this._executeCommandsSalvo(totalTime, commands, measurement); } else { return this._executeCommandsSequential(totalTime, commands, measurement); } } async _executeCommandsSalvo(totalTime, commands, measurement) { const start = Date.now(); // note - would be better to use monotonic time here but BigInt's are annoying await Promise.allSettled(commands.map(async (command) => { const targetTime = start + totalTime - (command.preliminary ?? 0); const timeToWait = targetTime - Date.now(); if (timeToWait > 0) { await sleep(timeToWait); } measurement?.executeCommand(command); try { await this.sendCommand(command); } catch (e) { this.logger.error('Error while executing command', e); } finally { measurement?.finishedCommandExecution(command); } })); } async _executeCommandsSequential(totalTime, commands, measurement) { const start = Date.now(); // note - would be better to use monotonic time here but BigInt's are annoying const commandQueues = _.groupBy(commands || [], (command) => command.queueId ?? '$$default'); await Promise.allSettled(Object.values(commandQueues).map(async (commandsInQueue) => { try { for (const command of commandsInQueue) { const targetTime = start + totalTime - (command.preliminary ?? 0); const timeToWait = targetTime - Date.now(); if (timeToWait > 0) { await sleep(timeToWait); } measurement?.executeCommand(command); try { await this.sendCommand(command); } catch (e) { this.logger.error('Error while executing command', e); } finally { measurement?.finishedCommandExecution(command); } } } catch (e) { this.logger.error('CommandExecutor', new Error('Error in _executeCommandsSequential')); } })); } } exports.CommandExecutor = CommandExecutor; async function sleep(duration) { return new Promise((resolve) => setTimeout(resolve, duration)); } //# sourceMappingURL=commandExecutor.js.map