* Spawn process and keep track on it. * * @param auto Automatically restart if exits early
(auto?: boolean)
| 103 | * @param auto Automatically restart if exits early |
| 104 | */ |
| 105 | public spawn(auto?: boolean): void { |
| 106 | if (!this.process && !this._isRestarting) { |
| 107 | // Reset the auto restart counter when we've manually / deliberately spawned the process |
| 108 | if (!auto) { |
| 109 | this.autoRestartCount = 0; |
| 110 | } |
| 111 | // Spawn process |
| 112 | log.debug('Server', `Executable: ${this.info.filename} - Arguments: ${this.info.arguments.join(' ')}`); |
| 113 | this.process = spawn(this.info.filename, this.info.arguments, { cwd: this.cwd, detached: this.detached, shell: this.shell, env: this.env}); |
| 114 | // Set start timestamp |
| 115 | this.startTime = Date.now(); |
| 116 | // Log |
| 117 | this.logContent(this.name + ' has been started'); |
| 118 | // Setup listeners |
| 119 | if (this.process.stdout) { |
| 120 | const stdout = readline.createInterface({ input: this.process.stdout }); |
| 121 | stdout.on('line', this.logContentAny); |
| 122 | } |
| 123 | if (this.process.stderr) { |
| 124 | const stderr = readline.createInterface({ input: this.process.stderr }); |
| 125 | stderr.on('line', this.logContentAny); |
| 126 | } |
| 127 | // Update state |
| 128 | this.setState(ProcessState.RUNNING); |
| 129 | // Register child process listeners |
| 130 | this.process.on('exit', (code, signal) => { |
| 131 | if (code) { this.logContent(`${this.name} exited with code ${code}`); } |
| 132 | else { this.logContent(`${this.name} exited with signal ${signal}`); } |
| 133 | const wasRunning = (this.state === ProcessState.RUNNING); |
| 134 | this.process = undefined; |
| 135 | this.emit('exit', code, signal); |
| 136 | this.setState(ProcessState.STOPPED); |
| 137 | if (this.autoRestart && wasRunning && code) { |
| 138 | if (this.autoRestartCount < MAX_RESTARTS) { |
| 139 | this.autoRestartCount++; |
| 140 | this.spawn(true); |
| 141 | } else { |
| 142 | this.logContent(`${this.name} Service crashed too frequently, leaving stopped.`); |
| 143 | } |
| 144 | } |
| 145 | }) |
| 146 | .on('error', error => { |
| 147 | this.logContent(`${this.name} failed to start - ${error.message}`); |
| 148 | this.setState(ProcessState.STOPPED); |
| 149 | this.process = undefined; |
| 150 | }); |
| 151 | } |
| 152 | } |
| 153 | |
| 154 | /** Politely ask the child process to exit (if it is running). */ |
| 155 | public async kill(): Promise<void> { |
no test coverage detected