import * as plugins from './plugins.js'; import { Smartshell, type IExecResultStreaming } from './classes.smartshell.js'; export interface IDeferred { resolve: (value?: T | PromiseLike) => void; reject: (reason?: any) => void; promise: Promise; } export class SmartExecution { public smartshell: Smartshell; public currentStreamingExecution: IExecResultStreaming; public commandString: string; private isRestartInProgress = false; private isAnotherRestartRequested = false; constructor(commandStringArg: string) { this.commandString = commandStringArg; } /** * Schedules a restart. If a restart is currently in progress, any additional calls * to restart will merge into a single additional restart request, which will only execute * once the current restart completes. */ public async restart(): Promise { if (this.isRestartInProgress) { // If there's already a restart in progress, just mark that another restart was requested this.isAnotherRestartRequested = true; return; } this.isRestartInProgress = true; try { if (!this.smartshell) { this.smartshell = new Smartshell({ executor: 'bash', }); } if (this.currentStreamingExecution) { await this.currentStreamingExecution.kill(); } this.currentStreamingExecution = await this.smartshell.execStreaming(this.commandString); } finally { this.isRestartInProgress = false; } // If another restart was requested while we were busy, we handle it now if (this.isAnotherRestartRequested) { this.isAnotherRestartRequested = false; await this.restart(); } } }