diff --git a/changelog.md b/changelog.md index 996ce0a..69ed3ff 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,11 @@ # Changelog +## 2024-12-09 - 3.2.0 - feat(SmartExecution) +Add support for scheduling restarts to SmartExecution + +- Introduced the ability to handle consecutive restarts efficiently in SmartExecution. +- Ensures that multiple restart requests merge into a single additional restart request if one is already in progress. + ## 2024-12-09 - 3.1.0 - feat(core) Refactor codebase and update dependencies. diff --git a/ts/00_commitinfo_data.ts b/ts/00_commitinfo_data.ts index cf02ec5..d5e814b 100644 --- a/ts/00_commitinfo_data.ts +++ b/ts/00_commitinfo_data.ts @@ -3,6 +3,6 @@ */ export const commitinfo = { name: '@push.rocks/smartshell', - version: '3.1.0', + version: '3.2.0', description: 'A library for executing shell commands using promises.' } diff --git a/ts/classes.smartexecution.ts b/ts/classes.smartexecution.ts index 293e51c..bc7710d 100644 --- a/ts/classes.smartexecution.ts +++ b/ts/classes.smartexecution.ts @@ -1,24 +1,55 @@ -import * as plugins from './plugins.js' +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; } - public async restart() { - if (!this.smartshell) { - this.smartshell = new Smartshell({ - executor: 'bash', - }); + /** + * 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; } - if (this.currentStreamingExecution) { - await this.currentStreamingExecution.kill(); + + 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(); } - this.currentStreamingExecution = await this.smartshell.execStreaming(this.commandString); } } \ No newline at end of file