mirror of
https://github.com/Hopiu/webapi-eca.git
synced 2026-03-16 22:10:31 +00:00
restructured the http listener
This commit is contained in:
parent
20748240c2
commit
e31da1e5a0
11 changed files with 175 additions and 74 deletions
|
|
@ -80,16 +80,16 @@ initRouting = ( port ) =>
|
|||
# - **`POST` to _"/user"_:** User requests are possible for all users with an account
|
||||
app.post '/usercommand', requestHandler.handleUserCommand
|
||||
try
|
||||
@server = app.listen parseInt( port ) || 8125 # inbound event channel
|
||||
server = app.listen parseInt( port ) || 8125 # inbound event channel
|
||||
###
|
||||
Error handling of the express port listener requires special attention,
|
||||
thus we have to catch the error, which is issued if the port is already in use.
|
||||
###
|
||||
@server.on 'listening', () =>
|
||||
addr = @server.address()
|
||||
server.on 'listening', () =>
|
||||
addr = server.address()
|
||||
if addr.port is not port
|
||||
@shutDownSystem()
|
||||
@server.on 'error', ( err ) =>
|
||||
server.on 'error', ( err ) =>
|
||||
if err.errno is 'EADDRINUSE'
|
||||
@log.error err, 'HL | http-port already in use, shutting down!'
|
||||
@shutDownSystem()
|
||||
|
|
@ -105,13 +105,16 @@ exports.addShutdownHandler = ( fShutDown ) =>
|
|||
@shutDownSystem = fShutDown
|
||||
requestHandler.addShutdownHandler fShutDown
|
||||
|
||||
###
|
||||
Shuts down the http listener.
|
||||
|
||||
@public shutDown()
|
||||
###
|
||||
exports.shutDown = () =>
|
||||
@log.warn 'HL | Shutting down HTTP listener'
|
||||
try
|
||||
@server.close()
|
||||
# There's no way to gracefully stop express from running, thus the main
|
||||
# module needs to call process.exit() at the very end of its existance... thanks
|
||||
# ###
|
||||
# Shuts down the http listener.
|
||||
|
||||
# @public shutDown()
|
||||
# ###
|
||||
# exports.shutDown = () =>
|
||||
# @log?.warn 'HL | Shutting down HTTP listener'
|
||||
# # Yeah I know the discussion... let's assume the system runs forever
|
||||
# process.exit()
|
||||
|
||||
|
|
|
|||
|
|
@ -41,8 +41,12 @@ exports = module.exports = ( args ) =>
|
|||
@crypto_key = "}f6y1y}B{.an$}2c$Yl.$mSnF\\HX149u*y8C:@kmN/520Gt\\v'+KFBnQ!\\r<>5X/xRI`sT<Iw;:DPV;4gy:qf]Zq{\"6sgK{,}^\"!]O;qBM3G?]h_`Psw=b6bVXKXry7*"
|
||||
@db = redis.createClient args[ 'db-port' ],
|
||||
'localhost', { connect_timeout: 2000 }
|
||||
# Eventually we try to connect to the wrong port, redis will emit an error that we
|
||||
# need to catch and take into account when answering the isConnected function call
|
||||
@db.on 'error', ( err ) =>
|
||||
@log.warn err, 'message from DB'
|
||||
if err.message.indexOf 'ECONNREFUSED' > -1
|
||||
@connRefused = true
|
||||
@log.error err, 'DB | Wrong port?'
|
||||
@ep = new IndexedModules( 'event-poller', @db, @log )
|
||||
@ai = new IndexedModules( 'action-invoker', @db, @log )
|
||||
|
||||
|
|
@ -54,17 +58,21 @@ ten attempts within five seconds, or nothing on success to the callback(err).
|
|||
@param {function} cb
|
||||
###
|
||||
exports.isConnected = ( cb ) =>
|
||||
if @db.connected then cb()
|
||||
if @db.connected
|
||||
cb()
|
||||
else
|
||||
numAttempts = 0
|
||||
fCheckConnection = =>
|
||||
if @db.connected
|
||||
@log.info 'DB | Successfully connected to DB!'
|
||||
cb()
|
||||
else if numAttempts++ < 10
|
||||
setTimeout fCheckConnection, 100
|
||||
if @connRefused
|
||||
cb new Error 'DB | Connection refused! Wrong port?'
|
||||
else
|
||||
cb new Error 'Connection to DB failed!'
|
||||
if @db.connected
|
||||
@log.info 'DB | Successfully connected to DB!'
|
||||
cb()
|
||||
else if numAttempts++ < 10
|
||||
setTimeout fCheckConnection, 100
|
||||
else
|
||||
cb new Error 'DB | Connection to DB failed!'
|
||||
setTimeout fCheckConnection, 100
|
||||
|
||||
###
|
||||
|
|
|
|||
|
|
@ -120,13 +120,14 @@ init = =>
|
|||
logconf: logconf
|
||||
# > Fetch the `http-port` argument
|
||||
args[ 'http-port' ] = parseInt argv.w || conf.getHttpPort()
|
||||
args[ 'db-port' ] = parseInt argv.w || conf.getDbPort()
|
||||
args[ 'db-port' ] = parseInt argv.d || conf.getDbPort()
|
||||
|
||||
@log.info 'RS | Initialzing DB'
|
||||
db args
|
||||
# > We only proceed with the initialization if the DB is ready
|
||||
db.isConnected ( err, result ) =>
|
||||
db.isConnected ( err ) =>
|
||||
if err
|
||||
@log.error 'RS | No DB connection, shutting down system!'
|
||||
shutDown()
|
||||
|
||||
else
|
||||
|
|
@ -163,7 +164,7 @@ Shuts down the server.
|
|||
shutDown = =>
|
||||
@log.warn 'RS | Received shut down command!'
|
||||
engine?.shutDown()
|
||||
http?.shutDown()
|
||||
# We need to force stop express (in http-listener module)
|
||||
process.exit()
|
||||
|
||||
###
|
||||
|
|
|
|||
|
|
@ -227,7 +227,7 @@ function preprocessActionArguments(evt, act, res) {
|
|||
}
|
||||
|
||||
exports.shutDown = function() {
|
||||
log.info('EN', 'Shutting down Poller and DB Link');
|
||||
if(log) log.info('EN', 'Shutting down Poller and DB Link');
|
||||
isRunning = false;
|
||||
if(poller) poller.send('cmd|shutdown');
|
||||
if(db) db.shutDown();
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ HTTP Listener
|
|||
|
||||
|
||||
initRouting = function(port) {
|
||||
var sess_sec;
|
||||
var server, sess_sec;
|
||||
app.use(express.cookieParser());
|
||||
sess_sec = "149u*y8C:@kmN/520Gt\\v'+KFBnQ!\\r<>5X/xRI`sT<Iw";
|
||||
app.use(express.session({
|
||||
|
|
@ -65,20 +65,20 @@ HTTP Listener
|
|||
app.post('/logout', requestHandler.handleLogout);
|
||||
app.post('/usercommand', requestHandler.handleUserCommand);
|
||||
try {
|
||||
_this.server = app.listen(parseInt(port) || 8125);
|
||||
server = app.listen(parseInt(port) || 8125);
|
||||
/*
|
||||
Error handling of the express port listener requires special attention,
|
||||
thus we have to catch the error, which is issued if the port is already in use.
|
||||
*/
|
||||
|
||||
_this.server.on('listening', function() {
|
||||
server.on('listening', function() {
|
||||
var addr;
|
||||
addr = _this.server.address();
|
||||
addr = server.address();
|
||||
if (addr.port === !port) {
|
||||
return _this.shutDownSystem();
|
||||
}
|
||||
});
|
||||
return _this.server.on('error', function(err) {
|
||||
return server.on('error', function(err) {
|
||||
if (err.errno === 'EADDRINUSE') {
|
||||
_this.log.error(err, 'HL | http-port already in use, shutting down!');
|
||||
return _this.shutDownSystem();
|
||||
|
|
@ -100,18 +100,4 @@ HTTP Listener
|
|||
return requestHandler.addShutdownHandler(fShutDown);
|
||||
};
|
||||
|
||||
/*
|
||||
Shuts down the http listener.
|
||||
|
||||
@public shutDown()
|
||||
*/
|
||||
|
||||
|
||||
exports.shutDown = function() {
|
||||
_this.log.warn('HL | Shutting down HTTP listener');
|
||||
try {
|
||||
return _this.server.close();
|
||||
} catch (_error) {}
|
||||
};
|
||||
|
||||
}).call(this);
|
||||
|
|
|
|||
|
|
@ -49,7 +49,10 @@ Persistence
|
|||
connect_timeout: 2000
|
||||
});
|
||||
_this.db.on('error', function(err) {
|
||||
return _this.log.warn(err, 'message from DB');
|
||||
if (err.message.indexOf('ECONNREFUSED' > -1)) {
|
||||
_this.connRefused = true;
|
||||
return _this.log.error(err, 'DB | Wrong port?');
|
||||
}
|
||||
});
|
||||
_this.ep = new IndexedModules('event-poller', _this.db, _this.log);
|
||||
return _this.ai = new IndexedModules('action-invoker', _this.db, _this.log);
|
||||
|
|
@ -71,13 +74,17 @@ Persistence
|
|||
} else {
|
||||
numAttempts = 0;
|
||||
fCheckConnection = function() {
|
||||
if (_this.db.connected) {
|
||||
_this.log.info('DB | Successfully connected to DB!');
|
||||
return cb();
|
||||
} else if (numAttempts++ < 10) {
|
||||
return setTimeout(fCheckConnection, 100);
|
||||
if (_this.connRefused) {
|
||||
return cb(new Error('DB | Connection refused! Wrong port?'));
|
||||
} else {
|
||||
return cb(new Error('Connection to DB failed!'));
|
||||
if (_this.db.connected) {
|
||||
_this.log.info('DB | Successfully connected to DB!');
|
||||
return cb();
|
||||
} else if (numAttempts++ < 10) {
|
||||
return setTimeout(fCheckConnection, 100);
|
||||
} else {
|
||||
return cb(new Error('DB | Connection to DB failed!'));
|
||||
}
|
||||
}
|
||||
};
|
||||
return setTimeout(fCheckConnection, 100);
|
||||
|
|
|
|||
|
|
@ -129,12 +129,13 @@ WebAPI-ECA Engine
|
|||
logconf: logconf
|
||||
};
|
||||
args['http-port'] = parseInt(argv.w || conf.getHttpPort());
|
||||
args['db-port'] = parseInt(argv.w || conf.getDbPort());
|
||||
args['db-port'] = parseInt(argv.d || conf.getDbPort());
|
||||
_this.log.info('RS | Initialzing DB');
|
||||
db(args);
|
||||
return db.isConnected(function(err, result) {
|
||||
return db.isConnected(function(err) {
|
||||
var cliArgs, poller;
|
||||
if (err) {
|
||||
_this.log.error('RS | No DB connection, shutting down system!');
|
||||
return shutDown();
|
||||
} else {
|
||||
_this.log.info('RS | Initialzing engine');
|
||||
|
|
@ -164,9 +165,6 @@ WebAPI-ECA Engine
|
|||
if (engine != null) {
|
||||
engine.shutDown();
|
||||
}
|
||||
if (http != null) {
|
||||
http.shutDown();
|
||||
}
|
||||
return process.exit();
|
||||
};
|
||||
|
||||
|
|
|
|||
79
testing/test_http-listener.coffee
Normal file
79
testing/test_http-listener.coffee
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
|
||||
path = require 'path'
|
||||
needle = require 'needle'
|
||||
logger = require path.join '..', 'js-coffee', 'logging'
|
||||
log = logger.getLogger
|
||||
nolog: true
|
||||
|
||||
|
||||
exports.testShutDown = ( test ) =>
|
||||
test.expect 1
|
||||
|
||||
http = require path.join '..', 'js-coffee', 'http-listener'
|
||||
http.addShutdownHandler () ->
|
||||
console.log 'shutdown handler called!'
|
||||
http.shutDown()
|
||||
test.done()
|
||||
process.exit()
|
||||
args = {
|
||||
logger: log
|
||||
}
|
||||
args[ 'http-port' ] = 8080
|
||||
http args
|
||||
test.ok true, 'yay'
|
||||
|
||||
fWait = () ->
|
||||
|
||||
needle.get 'localhost:8080/forge_modules', (err, resp, body) ->
|
||||
console.log 'http'
|
||||
# console.log http
|
||||
# console.log test
|
||||
# console.log err
|
||||
# console.log resp
|
||||
# console.log body
|
||||
test.done()
|
||||
if err
|
||||
console.log 'got an error on request'
|
||||
console.log err
|
||||
else
|
||||
console.log 'no err'
|
||||
if resp and resp.statusCode is 200
|
||||
console.log 'yay got valid answer'
|
||||
else console.log 'got an'
|
||||
try
|
||||
console.log 'trying to shutdown'
|
||||
console.log http
|
||||
http.shutDown()
|
||||
catch e
|
||||
console.log e
|
||||
|
||||
|
||||
setTimeout fWait, 1000
|
||||
|
||||
exports.testWrongPort = ( test ) =>
|
||||
test.expect 1
|
||||
test.ok true, 'yay'
|
||||
test.done()
|
||||
# http = require path.join '..', 'js-coffee', 'http-listener'
|
||||
# http.addShutDownHandler () ->
|
||||
|
||||
# test.done()
|
||||
# engine = cp.fork pth, [ '-n' ] # [ '-i' , 'warn' ]
|
||||
|
||||
# engine.on 'exit', ( code, signal ) ->
|
||||
# test.ok true, 'Engine stopped'
|
||||
# isRunning = false
|
||||
# test.done()
|
||||
|
||||
# fWaitForStartup = () ->
|
||||
# engine.send 'die'
|
||||
# setTimeout fWaitForDeath, 5000
|
||||
|
||||
# # Garbage collect eventually still running process
|
||||
# fWaitForDeath = () ->
|
||||
# if isRunning
|
||||
# test.ok false, '"testShutDown" Engine didn\'t shut down!'
|
||||
# engine.kill()
|
||||
# test.done()
|
||||
|
||||
# setTimeout fWaitForStartup, 1000
|
||||
|
|
@ -16,9 +16,9 @@ exports.tearDown = ( cb ) =>
|
|||
cb()
|
||||
|
||||
|
||||
###
|
||||
# Test AVAILABILITY
|
||||
###
|
||||
# ###
|
||||
# # Test AVAILABILITY
|
||||
# ###
|
||||
exports.Availability =
|
||||
testRequire: ( test ) =>
|
||||
test.expect 1
|
||||
|
|
@ -39,7 +39,7 @@ exports.Availability =
|
|||
|
||||
opts =
|
||||
logger: @log
|
||||
opts[ 'db-port' ] = 63214
|
||||
opts[ 'db-port' ] = 13410
|
||||
@db opts
|
||||
@db.isConnected ( err ) ->
|
||||
test.ok err, 'Still connected!?'
|
||||
|
|
|
|||
|
|
@ -9,9 +9,8 @@ path = require 'path'
|
|||
# @engine.send('die')
|
||||
# cb()
|
||||
|
||||
# # TODO wrong db-port or http-port will make the engine stop properly before starting
|
||||
# # goes hand in hand with wrong config file
|
||||
# # http command shutdown does it properly, as well as sending the process the die command
|
||||
# TODO test http shutdown command
|
||||
# TODO test wrong/invalid config file
|
||||
|
||||
exports.testShutDown = ( test ) =>
|
||||
test.expect 1
|
||||
|
|
@ -100,5 +99,24 @@ exports.testHttpPortInvalid = ( test ) =>
|
|||
test.ok false, '"testHttpPortInvalid" Engine didn\'t shut down!'
|
||||
test.done()
|
||||
|
||||
setTimeout fWaitForDeath, 1000
|
||||
|
||||
exports.testDbPortInvalid = ( test ) =>
|
||||
test.expect 1
|
||||
|
||||
isRunning = true
|
||||
pth = path.resolve 'js-coffee', 'webapi-eca'
|
||||
engine = cp.fork pth, ['-n', '-d', '10'] # [ '-i' , 'warn' ]
|
||||
engine.on 'exit', ( code, signal ) ->
|
||||
test.ok true, 'Engine stopped'
|
||||
isRunning = false
|
||||
test.done()
|
||||
|
||||
# Garbage collect eventually still running process
|
||||
fWaitForDeath = () =>
|
||||
engine.kill()
|
||||
if isRunning
|
||||
test.ok false, '"testHttpPortInvalid" Engine didn\'t shut down!'
|
||||
test.done()
|
||||
|
||||
setTimeout fWaitForDeath, 1000
|
||||
|
|
|
|||
|
|
@ -1,15 +1,16 @@
|
|||
#!/usr/bin/env node
|
||||
process.chdir(__dirname);
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var args = process.argv.slice(2);
|
||||
if( args[0] !== undefined ) {
|
||||
var fl = path.join('testing', args[0]);
|
||||
if (fs.existsSync(fl)) {
|
||||
require('nodeunit').reporters.default.run([fl]);
|
||||
} else {
|
||||
console.error('File not found!!');
|
||||
}
|
||||
process.chdir( __dirname );
|
||||
var fs = require( 'fs' );
|
||||
var path = require( 'path' );
|
||||
var nodeunit = require( 'nodeunit' );
|
||||
var args = process.argv.slice( 2 );
|
||||
if( args[ 0 ] !== undefined ) {
|
||||
var fl = path.resolve( args[ 0 ] );
|
||||
if ( fs.existsSync( fl ) ) {
|
||||
nodeunit.reporters.default.run( [ fl ] );
|
||||
} else {
|
||||
console.error( 'File not found!!' );
|
||||
}
|
||||
} else {
|
||||
require('nodeunit').reporters.default.run(['testing']);
|
||||
nodeunit.reporters.default.run( [ 'testing' ] );
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue