mirror of
https://github.com/openstf/stf
synced 2025-10-03 17:59:28 +02:00
90 lines
1.9 KiB
JavaScript
90 lines
1.9 KiB
JavaScript
var util = require('util')
|
|
var cp = require('child_process')
|
|
|
|
var Promise = require('bluebird')
|
|
|
|
function ExitError(code) {
|
|
Error.call(this)
|
|
this.name = 'ExitError'
|
|
this.code = code
|
|
this.message = util.format('Exit code "%d"', code)
|
|
Error.captureStackTrace(this, ExitError)
|
|
}
|
|
|
|
util.inherits(ExitError, Error)
|
|
|
|
// Export
|
|
module.exports.ExitError = ExitError
|
|
|
|
// Export
|
|
module.exports.fork = function() {
|
|
var resolver = Promise.defer()
|
|
var proc = cp.fork.apply(cp, arguments)
|
|
|
|
function sigintListener() {
|
|
proc.kill('SIGINT')
|
|
}
|
|
|
|
function sigtermListener() {
|
|
proc.kill('SIGTERM')
|
|
}
|
|
|
|
process.on('SIGINT', sigintListener)
|
|
process.on('SIGTERM', sigtermListener)
|
|
|
|
proc.on('error', function(err) {
|
|
resolver.reject(err)
|
|
proc.kill()
|
|
})
|
|
|
|
proc.on('exit', function(code, signal) {
|
|
if (signal) {
|
|
resolver.resolve(code)
|
|
}
|
|
else if (code > 0 && code !== 130 && code !== 143) {
|
|
resolver.reject(new ExitError(code))
|
|
}
|
|
else {
|
|
resolver.resolve(code)
|
|
}
|
|
})
|
|
|
|
return resolver.promise.cancellable()
|
|
.finally(function() {
|
|
process.removeListener('SIGINT', sigintListener)
|
|
process.removeListener('SIGTERM', sigtermListener)
|
|
})
|
|
.catch(Promise.CancellationError, function() {
|
|
return new Promise(function(resolve) {
|
|
proc.on('exit', function() {
|
|
resolve()
|
|
})
|
|
proc.kill()
|
|
})
|
|
})
|
|
}
|
|
|
|
// Export
|
|
module.exports.gracefullyKill = function(proc, timeout) {
|
|
function killer(signal) {
|
|
var deferred = Promise.defer()
|
|
|
|
function onExit() {
|
|
deferred.resolve()
|
|
}
|
|
|
|
proc.once('exit', onExit)
|
|
proc.kill(signal)
|
|
|
|
return deferred.promise.finally(function() {
|
|
proc.removeListener('exit', onExit)
|
|
})
|
|
}
|
|
|
|
return killer('SIGTERM')
|
|
.timeout(timeout)
|
|
.catch(function() {
|
|
return killer('SIGKILL')
|
|
.timeout(timeout)
|
|
})
|
|
}
|