"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; };