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

Replace device:support:quit with util:lifecycle, which is usable by non-device processes too.

This commit is contained in:
Simo Kinnunen 2014-04-01 21:41:58 +09:00
parent e17f306d30
commit d6604bcda8
11 changed files with 75 additions and 179 deletions

View file

@ -10,12 +10,12 @@ var split = require('split')
var logger = require('../../../util/logger') var logger = require('../../../util/logger')
var devutil = require('../../../util/devutil') var devutil = require('../../../util/devutil')
var lifecycle = require('../../../util/lifecycle')
module.exports = syrup.serial() module.exports = syrup.serial()
.dependency(require('../support/adb')) .dependency(require('../support/adb'))
.dependency(require('../support/quit'))
.dependency(require('../resources/remote')) .dependency(require('../resources/remote'))
.define(function(options, adb, quit, remote) { .define(function(options, adb, remote) {
var log = logger.createLogger('device:plugins:http') var log = logger.createLogger('device:plugins:http')
var service = { var service = {
@ -34,18 +34,11 @@ module.exports = syrup.serial()
, '--listen-http', service.port , '--listen-http', service.port
]) ])
.then(function(out) { .then(function(out) {
lifecycle.share('Remote shell', out)
out.pipe(split()) out.pipe(split())
.on('data', function(chunk) { .on('data', function(chunk) {
log.info('Remote says: "%s"', chunk) log.info('Remote says: "%s"', chunk)
}) })
.on('error', function(err) {
log.fatal('Remote shell had an error', err.stack)
quit.fatal()
})
.on('end', function() {
log.fatal('Remote shell ended')
quit.fatal()
})
}) })
.then(function() { .then(function() {
return devutil.waitForPort(adb, options.serial, service.port) return devutil.waitForPort(adb, options.serial, service.port)
@ -82,11 +75,7 @@ module.exports = syrup.serial()
var resolver = Promise.defer() var resolver = Promise.defer()
function resolve() { function resolve() {
proxyServer lifecycle.share('Proxy server', proxyServer)
.on('error', function(err) {
log.fatal('Proxy server had an error', err.stack)
quit.fatal()
})
resolver.resolve() resolver.resolve()
} }

View file

@ -11,14 +11,14 @@ var keyutil = require('../../../util/keyutil')
var streamutil = require('../../../util/streamutil') var streamutil = require('../../../util/streamutil')
var logger = require('../../../util/logger') var logger = require('../../../util/logger')
var ms = require('../../../wire/messagestream') var ms = require('../../../wire/messagestream')
var lifecycle = require('../../../util/lifecycle')
module.exports = syrup.serial() module.exports = syrup.serial()
.dependency(require('../support/adb')) .dependency(require('../support/adb'))
.dependency(require('../support/router')) .dependency(require('../support/router'))
.dependency(require('../support/push')) .dependency(require('../support/push'))
.dependency(require('../support/quit'))
.dependency(require('../resources/service')) .dependency(require('../resources/service'))
.define(function(options, adb, router, push, quit, apk) { .define(function(options, adb, router, push, apk) {
var log = logger.createLogger('device:plugins:input') var log = logger.createLogger('device:plugins:input')
var serviceQueue = [] var serviceQueue = []
@ -49,18 +49,11 @@ module.exports = syrup.serial()
)) ))
}) })
.then(function(out) { .then(function(out) {
lifecycle.share('InputAgent shell', out)
out.pipe(split()) out.pipe(split())
.on('data', function(chunk) { .on('data', function(chunk) {
log.info('Agent says: "%s"', chunk) log.info('Agent says: "%s"', chunk)
}) })
.on('error', function(err) {
log.fatal('InputAgent shell had an error', err.stack)
quit.fatal()
})
.on('end', function() {
log.fatal('InputAgent shell ended')
quit.fatal()
})
}) })
.then(function() { .then(function() {
return devutil.waitForPort(adb, options.serial, agent.port) return devutil.waitForPort(adb, options.serial, agent.port)
@ -69,14 +62,7 @@ module.exports = syrup.serial()
agent.socket = conn agent.socket = conn
agent.writer = new ms.DelimitingStream() agent.writer = new ms.DelimitingStream()
agent.writer.pipe(conn) agent.writer.pipe(conn)
conn.on('error', function(err) { lifecycle.share('InputAgent connection', conn)
log.fatal('InputAgent socket had an error', err.stack)
quit.fatal()
})
conn.on('end', function() {
log.fatal('InputAgent socket ended')
quit.fatal()
})
}) })
} }
@ -160,14 +146,7 @@ module.exports = syrup.serial()
}) })
service.writer = new ms.DelimitingStream() service.writer = new ms.DelimitingStream()
service.writer.pipe(conn) service.writer.pipe(conn)
conn.on('error', function(err) { lifecycle.share('InputService connection', conn)
log.fatal('InputService socket had an error', err.stack)
quit.fatal()
})
.on('end', function() {
log.fatal('InputService socket ended')
quit.fatal()
})
}) })
} }

View file

@ -3,29 +3,21 @@ var syrup = require('syrup')
var logger = require('../../../util/logger') var logger = require('../../../util/logger')
var wire = require('../../../wire') var wire = require('../../../wire')
var wireutil = require('../../../wire/util') var wireutil = require('../../../wire/util')
var lifecycle = require('../../../util/lifecycle')
module.exports = syrup.serial() module.exports = syrup.serial()
.dependency(require('../support/adb')) .dependency(require('../support/adb'))
.dependency(require('../support/router')) .dependency(require('../support/router'))
.dependency(require('../support/push')) .dependency(require('../support/push'))
.dependency(require('../support/quit'))
.dependency(require('./owner')) .dependency(require('./owner'))
.define(function(options, adb, router, push, quit, owner) { .define(function(options, adb, router, push, owner) {
var log = logger.createLogger('device:plugins:logcat') var log = logger.createLogger('device:plugins:logcat')
function openService() { function openService() {
log.info('Launching logcat service') log.info('Launching logcat service')
return adb.openLogcat(options.serial) return adb.openLogcat(options.serial)
.then(function(logcat) { .then(function(logcat) {
return logcat return lifecycle.share('Logcat', logcat)
.on('error', function(err) {
log.fatal('Logcat had an error', err)
quit.fatal()
})
.on('end', function() {
log.fatal('Logcat ended')
quit.fatal()
})
}) })
} }

View file

@ -4,11 +4,11 @@ var syrup = require('syrup')
var logger = require('../../../util/logger') var logger = require('../../../util/logger')
var wire = require('../../../wire') var wire = require('../../../wire')
var wireutil = require('../../../wire/util') var wireutil = require('../../../wire/util')
var lifecycle = require('../../../util/lifecycle')
module.exports = syrup.serial() module.exports = syrup.serial()
.dependency(require('../support/push')) .dependency(require('../support/push'))
.dependency(require('../support/quit')) .define(function(options, push) {
.define(function(options, push, quit) {
// Forward all logs // Forward all logs
logger.on('entry', function(entry) { logger.on('entry', function(entry) {
push.send([ push.send([
@ -25,7 +25,7 @@ module.exports = syrup.serial()
]) ])
}) })
quit.observe(function() { lifecycle.observe(function() {
// Let's give it some time to flush logs before dying // Let's give it some time to flush logs before dying
return Promise.delay(500) return Promise.delay(500)
}) })

View file

@ -5,6 +5,7 @@ var logger = require('../../../util/logger')
var wire = require('../../../wire') var wire = require('../../../wire')
var wireutil = require('../../../wire/util') var wireutil = require('../../../wire/util')
var devutil = require('../../../util/devutil') var devutil = require('../../../util/devutil')
var lifecycle = require('../../../util/lifecycle')
module.exports = syrup.serial() module.exports = syrup.serial()
.dependency(require('./identity')) .dependency(require('./identity'))
@ -13,9 +14,7 @@ module.exports = syrup.serial()
.dependency(require('../support/push')) .dependency(require('../support/push'))
.dependency(require('../support/sub')) .dependency(require('../support/sub'))
.dependency(require('../support/channels')) .dependency(require('../support/channels'))
.dependency(require('../support/quit')) .define(function(options, identity, input, router, push, sub, channels) {
.define(function(options, identity, input, router, push, sub, channels,
quit) {
var log = logger.createLogger('device:plugins:owner') var log = logger.createLogger('device:plugins:owner')
var owner = null var owner = null
@ -131,7 +130,7 @@ module.exports = syrup.serial()
} }
}) })
quit.observe(function() { lifecycle.observe(function() {
if (isGrouped()) { if (isGrouped()) {
leaveGroup() leaveGroup()
return Promise.delay(500) return Promise.delay(500)

View file

@ -3,12 +3,12 @@ var split = require('split')
var logger = require('../../../util/logger') var logger = require('../../../util/logger')
var devutil = require('../../../util/devutil') var devutil = require('../../../util/devutil')
var lifecycle = require('../../../util/lifecycle')
module.exports = syrup.serial() module.exports = syrup.serial()
.dependency(require('../support/adb')) .dependency(require('../support/adb'))
.dependency(require('../support/quit'))
.dependency(require('../resources/remote')) .dependency(require('../resources/remote'))
.define(function(options, adb, quit, remote) { .define(function(options, adb, remote) {
var log = logger.createLogger('device:plugins:stats') var log = logger.createLogger('device:plugins:stats')
var service = { var service = {
@ -24,33 +24,18 @@ module.exports = syrup.serial()
, '--listen-stats', service.port , '--listen-stats', service.port
]) ])
.then(function(out) { .then(function(out) {
lifecycle.share('Stats remote shell', out)
out.pipe(split()) out.pipe(split())
.on('data', function(chunk) { .on('data', function(chunk) {
log.info('Remote says: "%s"', chunk) log.info('Remote says: "%s"', chunk)
}) })
.on('error', function(err) {
log.fatal('Remote shell had an error', err.stack)
quit.fatal()
})
.on('end', function() {
log.fatal('Remote shell ended')
quit.fatal()
})
}) })
}) })
.then(function() { .then(function() {
return devutil.waitForPort(adb, options.serial, service.port) return devutil.waitForPort(adb, options.serial, service.port)
}) })
.then(function(conn) { .then(function(conn) {
conn.pipe(split()) return lifecycle.share('Stats connection', conn)
.on('error', function(err) {
log.fatal('Remote had an error', err.stack)
quit.fatal()
})
.on('end', function() {
log.fatal('Remote ended')
quit.fatal()
})
}) })
} }

View file

@ -6,13 +6,13 @@ var monkey = require('adbkit-monkey')
var wire = require('../../../wire') var wire = require('../../../wire')
var devutil = require('../../../util/devutil') var devutil = require('../../../util/devutil')
var logger = require('../../../util/logger') var logger = require('../../../util/logger')
var lifecycle = require('../../../util/lifecycle')
module.exports = syrup.serial() module.exports = syrup.serial()
.dependency(require('../support/adb')) .dependency(require('../support/adb'))
.dependency(require('../support/router')) .dependency(require('../support/router'))
.dependency(require('../support/quit'))
.dependency(require('../resources/remote')) .dependency(require('../resources/remote'))
.define(function(options, adb, router, quit, remote) { .define(function(options, adb, router, remote) {
var log = logger.createLogger('device:plugins:touch') var log = logger.createLogger('device:plugins:touch')
var service = { var service = {
@ -30,18 +30,11 @@ module.exports = syrup.serial()
]) ])
}) })
.then(function(out) { .then(function(out) {
lifecycle.share('Touch remote shell', out)
out.pipe(split()) out.pipe(split())
.on('data', function(chunk) { .on('data', function(chunk) {
log.info('Remote says: "%s"', chunk) log.info('Remote says: "%s"', chunk)
}) })
.on('error', function(err) {
log.fatal('Remote had an error', err.stack)
quit.fatal()
})
.on('end', function() {
log.fatal('Remote ended')
quit.fatal()
})
}) })
.then(function() { .then(function() {
return devutil.waitForPort(adb, options.serial, service.port) return devutil.waitForPort(adb, options.serial, service.port)
@ -50,15 +43,7 @@ module.exports = syrup.serial()
return Promise.promisifyAll(monkey.connectStream(conn)) return Promise.promisifyAll(monkey.connectStream(conn))
}) })
.then(function(monkey) { .then(function(monkey) {
return monkey return lifecycle.share('Touch monkey', monkey)
.on('error', function(err) {
log.fatal('Monkey had an error', err.stack)
quit.fatal()
})
.on('end', function() {
log.fatal('Monkey ended')
quit.fatal()
})
}) })
} }

View file

@ -1,38 +0,0 @@
var Promise = require('bluebird')
var syrup = require('syrup')
var logger = require('../../../util/logger')
module.exports = syrup.serial()
.define(function() {
var log = logger.createLogger('device:support:quit')
var cleanup = []
function graceful() {
log.info('Winding down for graceful exit')
var wait = Promise.all(cleanup.map(function(fn) {
return fn()
}))
return wait.then(function() {
process.exit(0)
})
}
function fatal() {
log.fatal('Shutting down due to fatal error')
process.exit(1)
}
process.on('SIGINT', graceful)
process.on('SIGTERM', graceful)
return {
graceful: graceful
, fatal: fatal
, observe: function(promise) {
cleanup.push(promise)
}
}
})

View file

@ -5,10 +5,10 @@ var logger = require('../util/logger')
var wire = require('../wire') var wire = require('../wire')
var wireutil = require('../wire/util') var wireutil = require('../wire/util')
var dbapi = require('../db/api') var dbapi = require('../db/api')
var lifecycle = require('../util/lifecycle')
module.exports = function(options) { module.exports = function(options) {
var log = logger.createLogger('reaper') var log = logger.createLogger('reaper')
, quit = Promise.defer()
, timer , timer
if (options.name) { if (options.name) {
@ -40,28 +40,10 @@ module.exports = function(options) {
}) })
.catch(function(err) { .catch(function(err) {
log.error('Failed to load device list: ', err.message, err.stack) log.error('Failed to load device list: ', err.message, err.stack)
quit.reject(err) lifecycle.fatal()
}) })
} }
timer = setInterval(reap, options.reapInterval) timer = setInterval(reap, options.reapInterval)
process.on('SIGINT', function() {
quit.resolve()
})
process.on('SIGTERM', function() {
quit.resolve()
})
quit.promise
.then(function() {
process.exit(0)
})
.catch(function(err) {
log.fatal('Error caused quit: ', err.stack)
process.exit(1)
})
log.info('Reaping devices with no heartbeat') log.info('Reaping devices with no heartbeat')
} }

47
lib/util/lifecycle.js Normal file
View file

@ -0,0 +1,47 @@
var Promise = require('bluebird')
var logger = require('./logger')
var log = logger.createLogger('util:lifecycle')
function Lifecycle() {
this.observers = []
process.on('SIGINT', this.graceful.bind(this))
process.on('SIGTERM', this.graceful.bind(this))
}
Lifecycle.prototype.share = function(name, emitter) {
emitter.on('end', function() {
log.fatal('%s ended; we shall share its fate', name)
this.fatal()
}.bind(this))
emitter.on('error', function(err) {
log.fatal('%s had an error', name, err.stack)
this.fatal()
}.bind(this))
return emitter
}
Lifecycle.prototype.graceful = function() {
log.info('Winding down for graceful exit')
var wait = Promise.all(this.observers.map(function(fn) {
return fn()
}))
return wait.then(function() {
process.exit(0)
})
}
Lifecycle.prototype.fatal = function() {
log.fatal('Shutting down due to fatal error')
process.exit(1)
}
Lifecycle.prototype.observe = function(promise) {
this.observers.push(promise)
}
module.exports = new Lifecycle()

View file

@ -1,24 +0,0 @@
var events = require('events')
var util = require('util')
function Vitals() {
events.EventEmitter.call(this)
}
util.inherits(Vitals, events.EventEmitter)
Vitals.prototype.register = function(name, stream) {
var that = this
stream.on('end', function() {
that.emit('end', name)
})
stream.on('error', function(err) {
that.emit('error', name, err)
})
return stream
}
module.exports = Vitals