Files
BotanSS/net/AppDomain.js
T

89 lines
1.7 KiB
JavaScript

"use strict";
const cluster = require( "cluster" );
const cl = global.botanLoader;
const Dragonfly = global.Dragonfly;
const domain = require('domain');
const http = require( "http" );
class Serving
{
constructor( server, handler, req, res )
{
this.server = server;
this.handler = handler;
this.req = req;
this.res = res;
var _self = this;
var _rejection = ( e, p ) => _self.tryExitGracefully( e );
var _uncaught = e => _self.tryExitGracefully( e );
process
.once( "unhandledRejection", _rejection )
.once( "uncaughtException", _uncaught )
;
res._rejection = _rejection;
res._uncaught = _uncaught;
var d = domain.create();
d.addListener( 'error', ( e ) => _self.tryExitGracefully( e ) );
d.add( req );
d.add( res );
d.run( () => _self.handler( req, res ) );
}
tryExitGracefully( e )
{
Dragonfly.Error( e.stack || e );
try
{
var killtimer = setTimeout( () => process.exit(1), 3000 );
killtimer.unref();
this.server.close();
// Message is hardcoded to prevent further exceptions occured
// This function must be bug-free
this.res.statusCode = 500;
this.res.setHeader( 'Content-Type', 'text/plain' );
this.res.end( e.message || e );
}
catch( ex )
{
Dragonfly.Error( ex.stack );
}
finally
{
cluster.worker.disconnect();
}
}
}
module.exports = function( handler, port )
{
if( cluster.isMaster )
{
Dragonfly.Debug( "Not Listening on master" );
return;
}
var server = null;
server = http.createServer(
function( req, res )
{
res._hrtime = process.hrtime.bigint();
new Serving( server, handler, req, res );
}
);
server.listen( port );
Dragonfly.Info( "Listening on: " + port, Dragonfly.Visibility.VISIBLE );
return server;
};