From 0e00149cacc73e92f92083ca53a241a62355610d Mon Sep 17 00:00:00 2001 From: Konstantin Upir Date: Sat, 25 Mar 2023 14:43:37 +0100 Subject: [PATCH 1/2] fix gracefulExit --- lib/multi-bar.js | 23 ++++++++------------ lib/shutdown-listener-tmp.js | 41 ++++++++++++++++++++++++++++++++++++ lib/shutdown-listener.js | 41 ++++++++++++++++++++++++++++++++++++ lib/single-bar.js | 22 +++++++------------ 4 files changed, 99 insertions(+), 28 deletions(-) create mode 100644 lib/shutdown-listener-tmp.js create mode 100644 lib/shutdown-listener.js diff --git a/lib/multi-bar.js b/lib/multi-bar.js index d40ccfc..37092db 100644 --- a/lib/multi-bar.js +++ b/lib/multi-bar.js @@ -2,6 +2,7 @@ const _Terminal = require('./terminal'); const _BarElement = require('./generic-bar'); const _options = require('./options'); const _EventEmitter = require('events'); +const _ShutdownListener = require('./shutdown-listener.js'); // Progress-Bar constructor module.exports = class MultiBar extends _EventEmitter{ @@ -33,8 +34,9 @@ module.exports = class MultiBar extends _EventEmitter{ // logging output buffer this.loggingBuffer = []; - // callback used for gracefulExit - this.sigintCallback = null; + // add handler to restore cursor settings (stop the bar) on SIGINT/SIGTERM ? + const signals = ['SIGINT', 'SIGTERM']; + this.shuthdownListener = new _ShutdownListener(signals, this.stop.bind(this)); } // add a new bar to the stack @@ -65,12 +67,10 @@ module.exports = class MultiBar extends _EventEmitter{ } // add handler to restore cursor settings (stop the bar) on SIGINT/SIGTERM ? - if (this.sigintCallback === null && this.options.gracefulExit){ - this.sigintCallback = this.stop.bind(this); - process.once('SIGINT', this.sigintCallback); - process.once('SIGTERM', this.sigintCallback); + if (this.options.gracefulExit){ + this.shuthdownListener.attach(); } - + // multiprogress already active ? if (!this.isActive){ // hide the cursor ? @@ -188,13 +188,6 @@ module.exports = class MultiBar extends _EventEmitter{ clearTimeout(this.timer); this.timer = null; - // remove sigint listener - if (this.sigintCallback){ - process.removeListener('SIGINT', this.sigintCallback); - process.removeListener('SIGTERM', this.sigintCallback); - this.sigintCallback = null; - } - // set flag this.isActive = false; @@ -239,6 +232,8 @@ module.exports = class MultiBar extends _EventEmitter{ this.terminal.newline(); } + this.shuthdownListener.detach(); + // trigger event this.emit('stop'); } diff --git a/lib/shutdown-listener-tmp.js b/lib/shutdown-listener-tmp.js new file mode 100644 index 0000000..dfe571e --- /dev/null +++ b/lib/shutdown-listener-tmp.js @@ -0,0 +1,41 @@ + +module.exports = class ShutdownListener { + constructor(signals, cleanupFunction, processOverride) { + this._signals = signals; + this._isSignalReceived = false; + this._isAttached = false; + this._process = processOverride ? processOverride : process; + this._handler = (signal) => { + if (this._isSignalReceived) { + return; + } + try { + this._isSignalReceived = true; + cleanupFunction(); + } catch (e) { + console.log(e); + } finally { + this._signals.forEach(sig => this._process.removeListener(sig, this._handler)); + this._process.kill(this._process.pid, signal); + } + } + } + attach() { + if (this._isAttached) { + return; + } + console.log('attach'); + this._signals.forEach(sig => { + this._process.on(sig, this._handler) + }); + this._isAttached = true; + } + detach() { + if (this._isSignalReceived) { + return; + } + this._signals.forEach(sig => this._process.removeListener(sig, this._handler)); + this._isAttached = false; + console.log('detach'); + } +} diff --git a/lib/shutdown-listener.js b/lib/shutdown-listener.js new file mode 100644 index 0000000..f19d93f --- /dev/null +++ b/lib/shutdown-listener.js @@ -0,0 +1,41 @@ + +module.exports = class ShutdownListener { + constructor(signals, cleanupFunction, processOverride) { + this._signals = signals; + this._isSignalReceived = false; + this._isAttached = false; + this._process = processOverride ? processOverride : process; + this._handler = (signal) => { + if (this._isSignalReceived) { + return; + } + this._isSignalReceived = true; + Promise.resolve(cleanupFunction()) + .catch((e) => { + console.log(e); + }) + .then(() => { + this._signals.forEach(sig => this._process.removeListener(sig, this._handler)); + this._process.kill(this._process.pid, signal); + }) + } + } + + attach() { + if (this._isAttached) { + return; + } + this._signals.forEach(sig => { + this._process.on(sig, this._handler) + }); + this._isAttached = true; + } + + detach() { + if (this._isSignalReceived) { + return; + } + this._signals.forEach(sig => this._process.removeListener(sig, this._handler)); + this._isAttached = false; + } +} diff --git a/lib/single-bar.js b/lib/single-bar.js index e8235e4..42866bb 100644 --- a/lib/single-bar.js +++ b/lib/single-bar.js @@ -1,5 +1,6 @@ const _GenericBar = require('./generic-bar'); const _options = require('./options'); +const _ShutdownListener = require("./shutdown-listener.js"); // Progress-Bar constructor module.exports = class SingleBar extends _GenericBar{ @@ -18,8 +19,9 @@ module.exports = class SingleBar extends _GenericBar{ // update interval this.schedulingRate = (this.terminal.isTTY() ? this.options.throttleTime : this.options.notTTYSchedule); - // callback used for gracefulExit - this.sigintCallback = null; + // add handler to restore cursor settings (stop the bar) on SIGINT/SIGTERM ? + const signals = ['SIGINT', 'SIGTERM']; + this.shuthdownListener = new _ShutdownListener(signals, this.stop.bind(this)); } // internal render function @@ -66,10 +68,8 @@ module.exports = class SingleBar extends _GenericBar{ } // add handler to restore cursor settings (stop the bar) on SIGINT/SIGTERM ? - if (this.sigintCallback === null && this.options.gracefulExit){ - this.sigintCallback = this.stop.bind(this); - process.once('SIGINT', this.sigintCallback); - process.once('SIGTERM', this.sigintCallback); + if (this.options.gracefulExit){ + this.shuthdownListener.attach(); } // save current cursor settings @@ -99,13 +99,6 @@ module.exports = class SingleBar extends _GenericBar{ return; } - // remove sigint listener - if (this.sigintCallback){ - process.removeListener('SIGINT', this.sigintCallback); - process.removeListener('SIGTERM', this.sigintCallback); - this.sigintCallback = null; - } - // trigger final rendering this.render(); @@ -137,5 +130,6 @@ module.exports = class SingleBar extends _GenericBar{ // new line on complete this.terminal.newline(); } + this.shuthdownListener.detach(); } -} \ No newline at end of file +} From 33ab5b06c9432c9c0739f1b669aba1cdd8de4238 Mon Sep 17 00:00:00 2001 From: Kostia Upir Date: Sun, 26 Mar 2023 22:24:21 +0300 Subject: [PATCH 2/2] Delete shutdown-listener-tmp.js --- lib/shutdown-listener-tmp.js | 41 ------------------------------------ 1 file changed, 41 deletions(-) delete mode 100644 lib/shutdown-listener-tmp.js diff --git a/lib/shutdown-listener-tmp.js b/lib/shutdown-listener-tmp.js deleted file mode 100644 index dfe571e..0000000 --- a/lib/shutdown-listener-tmp.js +++ /dev/null @@ -1,41 +0,0 @@ - -module.exports = class ShutdownListener { - constructor(signals, cleanupFunction, processOverride) { - this._signals = signals; - this._isSignalReceived = false; - this._isAttached = false; - this._process = processOverride ? processOverride : process; - this._handler = (signal) => { - if (this._isSignalReceived) { - return; - } - try { - this._isSignalReceived = true; - cleanupFunction(); - } catch (e) { - console.log(e); - } finally { - this._signals.forEach(sig => this._process.removeListener(sig, this._handler)); - this._process.kill(this._process.pid, signal); - } - } - } - attach() { - if (this._isAttached) { - return; - } - console.log('attach'); - this._signals.forEach(sig => { - this._process.on(sig, this._handler) - }); - this._isAttached = true; - } - detach() { - if (this._isSignalReceived) { - return; - } - this._signals.forEach(sig => this._process.removeListener(sig, this._handler)); - this._isAttached = false; - console.log('detach'); - } -}