Skip to content
51 changes: 48 additions & 3 deletions lib/support/processRunner.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@ var util = require('./util')()
module.exports = function () {
var isWin = /^win/.test(process.platform)

var run = function (mode, container, exitCb, cb) {
var commonRun = function (isPrerun, mode, container, exitCb, cb) {
if (isPrerun && container.process) {
container.process.flags.prerunning = true
}

var child = {}
var cwd = container.path
var called = false
Expand All @@ -34,7 +38,8 @@ module.exports = function () {
var env
var toks

toks = util.tokenizeCommand(container.run)
var command = isPrerun ? container.prerun : container.run
toks = util.tokenizeCommand(command)
if (container.type === 'node') {
cmd = process.argv[0]

Expand Down Expand Up @@ -63,18 +68,35 @@ module.exports = function () {
options.stdio[3] = 'ipc'
}

if (isPrerun) {
console.log('pre-run step: ' + container.name + ' [' + container.prerun + ']')
}

child = spawn(cmd, args, options)
child.unref()

child.on('error', function (err) {
if (!called) {
if (isPrerun) {
console.log('pre-run step had errors')
if (container.process) {
container.process.flags.prerunning = false
}
}

called = true
exitCb(err, container, child, -1)
}
})

child.on('exit', function (code) {
if (!called) {
if (isPrerun) {
console.log('pre-run step completed successfully')
if (container.process) {
container.process.flags.prerunning = false
}
}
called = true
exitCb(null, container, child, code)
}
Expand All @@ -90,11 +112,33 @@ module.exports = function () {
cb(null, child)
}

var prerun = function (mode, container, exitCb, cb) {
var runModeIsPrerun = true
commonRun(runModeIsPrerun, mode, container, exitCb, cb)
}

var run = function (mode, container, exitCb, cb) {
var runModeIsPrerun = false
commonRun(runModeIsPrerun, mode, container, exitCb, cb)
}

var start = function (system, mode, container, exitCb, cb) {
if (container && container.run) {
run(mode, container, exitCb, cb)
if (container.type === 'process' && container.prerun) {
// if there's a prerun task then execute that before running
prerun(mode, container, function (err, child) {
// when the pre-run task has exited we can continue
if (err) {
cb("prerun step error: " + err)
} else {
run(mode, container, exitCb, cb)
}
}, function () {
// for the pre-run step we ignore standard callback
})
} else {
run(mode, container, exitCb, cb)
}
} else {
console.log('warning: ' + container.name + ' not started, missing execute statement')
cb(container.name + ' not started, missing execute statement')
Expand Down Expand Up @@ -151,6 +195,7 @@ module.exports = function () {
c.run = command
c.name = c.name + '_' + commandName
c.type = 'process'
c.prerun = undefined
start(system, 'live', c, exitCb(cb), function (err, child) {

process = {identifier: c.name,
Expand Down
6 changes: 4 additions & 2 deletions lib/support/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,15 @@ module.exports = function () {
if (hidePid) {
return container.process.colour(line) + '\n'
} else {
return container.process.colour('[' + container.name + ' - ' + container.process.child.pid + ']: ' + line) + '\n'
var pid = (container.process.child && container.process.child.pid) || 'unknown'
return container.process.colour('[' + container.name + ' - ' + pid + ']: ' + line) + '\n'
}
}
})

var errorColorizer = split(function (line) {
return chalk.red('[' + container.name + ' - ' + container.process.child.pid + ']: ' + line) + '\n'
var pid = (container.process.child && container.process.child.pid) || 'unknown'
return chalk.red('[' + container.name + ' - ' + pid + ']: ' + line) + '\n'
})

var logStream = fs.createWriteStream(logPath + '/' + container.name + '.log')
Expand Down
11 changes: 8 additions & 3 deletions lib/system.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,14 @@ module.exports = function () {
return function (pth) {
console.log('[' + container.name + '] file change: ' + path.basename(pth))

if ((container.process && container.process.flags.running)) {
if (container.process && container.process.flags.running) {
var restartCausedByPrerun = container.process.flags.restarting && container.prerun;
container.process.flags.restarting = true
stopContainer(container, function () {})
if (!restartCausedByPrerun) {
stopContainer(container, function () {})
}
} else if (container.process && container.process.flags.prerunning) {
// Do nothing
} else {
startContainer(container, function () {})
}
Expand Down Expand Up @@ -148,7 +153,7 @@ module.exports = function () {
var stopContainer = function (container, cb) {
container.process.flags.stopping = true
runner.stop(container, container.process.child.pid, function () {
if (container.process.monitor && !container.process.flags.restarting) {
if (container.process.monitor) {
directoryWatcher.stop(container.process.monitor)
container.process.monitor = null
}
Expand Down
14 changes: 14 additions & 0 deletions test/fixture/system/fuge/prerun.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
prerun:
type: process
path: ../prerun
prerun: node prerunbuild.js
run: node prerun.js
ports:
- main=8002
prerunfail:
type: process
path: ../prerun
prerun: xxxxxxxxxxxxxx
run: node prerun.js
ports:
- main=8002
11 changes: 11 additions & 0 deletions test/fixture/system/prerun/prerun.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
'use strict'

var http = require('http')
var resp = { resp: 'Hello World!\n' }

var server = http.createServer(function (request, response) {
response.writeHead(200, {'Content-Type': 'text/plain'})
response.end(resp.resp)
})
server.listen(8002)
console.log('Server running at http://127.0.0.1:8002/')
1 change: 1 addition & 0 deletions test/fixture/system/prerun/prerunbuild.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

31 changes: 31 additions & 0 deletions test/processRunner.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -193,3 +193,34 @@ test('process kill test', function (t) {
})
})


test('prerun test 1', function (t) {
t.plan(4)

config.load(path.join(__dirname, 'fixture', 'system', 'fuge', 'prerun.yml'), function (err, system) {
t.equal(err, null)
runner.start(system, 'live', system.topology.containers.prerun, exitCb, function (err, child) {
t.equal(null, err)
t.notEqual(undefined, child.pid)

setTimeout(function () {
runner.stop(system.topology.containers.prerun, child.pid, function (err) {
t.equal(null, err)
})
}, 100)
})
})
})

test('prerun test 2 (failure test)', function (t) {
t.plan(3)

config.load(path.join(__dirname, 'fixture', 'system', 'fuge', 'prerun.yml'), function (err, system) {
t.equal(err, null)

runner.start(system, 'live', system.topology.containers.prerunfail, exitCb, function (err, child) {
t.notEqual(null, err)
t.equal(undefined, child)
})
})
})