timeline-state-resolver
Version:
Have timeline, control stuff
77 lines • 3.26 kB
JavaScript
;
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