1
0
Fork 0
mirror of https://github.com/openstf/stf synced 2025-10-04 10:19:30 +02:00

Shut down stf local in proper order so that the console doesn't get ugly.

This commit is contained in:
Simo Kinnunen 2014-03-18 17:14:33 +09:00
parent 78b768406a
commit aec95d87a4
2 changed files with 130 additions and 95 deletions

View file

@ -459,96 +459,102 @@ program
var log = logger.createLogger('cli') var log = logger.createLogger('cli')
, options = cliutil.lastArg(arguments) , options = cliutil.lastArg(arguments)
// app triproxy var procs = [
procutil.fork(__filename, [ // app triproxy
'triproxy', 'app001' procutil.fork(__filename, [
, '--bind-pub', options.bindAppPub 'triproxy', 'app001'
, '--bind-dealer', options.bindAppDealer , '--bind-pub', options.bindAppPub
, '--bind-pull', options.bindAppPull , '--bind-dealer', options.bindAppDealer
]) , '--bind-pull', options.bindAppPull
.catch(function(err) { ])
log.error('app triproxy died', err.stack)
})
// device triproxy // device triproxy
procutil.fork(__filename, [ , procutil.fork(__filename, [
'triproxy', 'dev001' 'triproxy', 'dev001'
, '--bind-pub', options.bindDevPub , '--bind-pub', options.bindDevPub
, '--bind-dealer', options.bindDevDealer , '--bind-dealer', options.bindDevDealer
, '--bind-pull', options.bindDevPull , '--bind-pull', options.bindDevPull
]) ])
.catch(function(err) {
log.error('device triproxy died', err.stack)
})
// processor one // processor one
procutil.fork(__filename, [ , procutil.fork(__filename, [
'processor', 'proc001' 'processor', 'proc001'
, '--connect-app-dealer', options.bindAppDealer , '--connect-app-dealer', options.bindAppDealer
, '--connect-dev-dealer', options.bindDevDealer , '--connect-dev-dealer', options.bindDevDealer
]) ])
.catch(function(err) {
log.error('processor 001 died', err.stack)
})
// processor two // processor two
procutil.fork(__filename, [ , procutil.fork(__filename, [
'processor', 'proc002' 'processor', 'proc002'
, '--connect-app-dealer', options.bindAppDealer , '--connect-app-dealer', options.bindAppDealer
, '--connect-dev-dealer', options.bindDevDealer , '--connect-dev-dealer', options.bindDevDealer
]) ])
.catch(function(err) {
log.error('processor 002 died', err.stack)
})
// reaper one // reaper one
procutil.fork(__filename, [ , procutil.fork(__filename, [
'reaper', 'reaper001' 'reaper', 'reaper001'
, '--connect-push', options.bindDevPull , '--connect-push', options.bindDevPull
]) ])
.catch(function(err) {
log.error('reaper 001 died', err.stack)
})
// provider // provider
procutil.fork(__filename, [ , procutil.fork(__filename, [
'provider' 'provider'
, '--name', options.provider , '--name', options.provider
, '--connect-sub', options.bindDevPub , '--connect-sub', options.bindDevPub
, '--connect-push', options.bindDevPull , '--connect-push', options.bindDevPull
].concat(cliutil.allUnknownArgs(arguments))) ].concat(cliutil.allUnknownArgs(arguments)))
.catch(function(err) {
log.error('provider died', err.stack)
})
// auth-mock // auth-mock
procutil.fork(__filename, [ , procutil.fork(__filename, [
'auth-mock' 'auth-mock'
, '--port', options.authPort , '--port', options.authPort
, '--secret', options.authSecret , '--secret', options.authSecret
, '--app-url', util.format('http://localhost:%d/', options.appPort) , '--app-url', util.format('http://localhost:%d/', options.appPort)
]) ])
.catch(function(err) {
log.error('auth-mock died', err.stack)
})
// app // app
procutil.fork(__filename, [ , procutil.fork(__filename, [
'app' 'app'
, '--port', options.appPort , '--port', options.appPort
, '--secret', options.authSecret , '--secret', options.authSecret
, '--auth-url', util.format('http://localhost:%d/', options.authPort) , '--auth-url', util.format('http://localhost:%d/', options.authPort)
, '--connect-sub', options.bindAppPub , '--connect-sub', options.bindAppPub
, '--connect-push', options.bindAppPull , '--connect-push', options.bindAppPull
].concat(function() { ].concat(function() {
var extra = [] var extra = []
if (options.disableWatch) { if (options.disableWatch) {
extra.push('--disable-watch') extra.push('--disable-watch')
} }
return extra return extra
}())) }()))
]
function shutdown() {
log.info('Shutting down all child processes')
procs.forEach(function(proc) {
proc.cancel()
})
return Promise.settle(procs)
}
process.on('SIGINT', function() {
log.info('Received SIGINT, waiting for processes to terminate')
})
process.on('SIGTERM', function() {
log.info('Received SIGTERM, waiting for processes to terminate')
})
Promise.all(procs)
.then(function() {
process.exit(0)
})
.catch(function(err) { .catch(function(err) {
log.error('app died', err.stack) log.fatal('Child process had an error', err.stack)
return shutdown()
.then(function() {
process.exit(1)
})
}) })
}) })

View file

@ -4,9 +4,10 @@ var cp = require('child_process')
var Promise = require('bluebird') var Promise = require('bluebird')
function ExitError(code) { function ExitError(code) {
Error.call(this, util.format('Exit code "%d"', code)) Error.call(this)
this.name = 'ExitError' this.name = 'ExitError'
this.code = code this.code = code
this.message = util.format('Exit code "%d"', code)
Error.captureStackTrace(this, ExitError) Error.captureStackTrace(this, ExitError)
} }
@ -17,22 +18,50 @@ module.exports.ExitError = ExitError
// Export // Export
module.exports.fork = function() { module.exports.fork = function() {
var args = arguments var resolver = Promise.defer()
var proc = cp.fork.apply(cp, arguments)
return new Promise(function(resolve, reject) { function sigintListener() {
var proc = cp.fork.apply(cp, args) proc.kill('SIGINT')
}
proc.on('error', function(err) { function sigtermListener() {
reject(err) proc.kill('SIGTERM')
proc.kill() }
})
proc.on('exit', function(code) { process.on('SIGINT', sigintListener)
if (code > 0) { process.on('SIGTERM', sigtermListener)
reject(new ExitError(code))
} 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(err) {
return new Promise(function(resolve, reject) {
proc.on('exit', function() {
resolver.resolve()
})
proc.kill()
})
})
} }
// Export // Export