Rewrite AppDomain to handle uncaughts & promises
This commit is contained in:
		
							
								
								
									
										106
									
								
								net/AppDomain.js
									
									
									
									
									
								
							
							
						
						
									
										106
									
								
								net/AppDomain.js
									
									
									
									
									
								
							@@ -1,70 +1,88 @@
 | 
			
		||||
var cl = global.botanLoader;
 | 
			
		||||
var Dragonfly = global.Dragonfly;
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
var domain = require('domain');
 | 
			
		||||
const cluster = require( "cluster" );
 | 
			
		||||
const cl = global.botanLoader;
 | 
			
		||||
const Dragonfly = global.Dragonfly;
 | 
			
		||||
 | 
			
		||||
var FatalError = cl.load( "botanss.errors.FatalError" );
 | 
			
		||||
const domain = require('domain');
 | 
			
		||||
const http = require( "http" );
 | 
			
		||||
 | 
			
		||||
// Message is hardcoded to prevent further exceptions occured
 | 
			
		||||
// This function must be bug-free
 | 
			
		||||
function server500( response, e )
 | 
			
		||||
class Serving
 | 
			
		||||
{
 | 
			
		||||
	response.statusCode = 500;
 | 
			
		||||
	response.setHeader( 'Content-Type', 'text/plain' );
 | 
			
		||||
	response.end( e.message || e );
 | 
			
		||||
}
 | 
			
		||||
	constructor( server, handler, req, res )
 | 
			
		||||
	{
 | 
			
		||||
		this.server = server;
 | 
			
		||||
		this.handler = handler;
 | 
			
		||||
		this.req = req;
 | 
			
		||||
		this.res = res;
 | 
			
		||||
 | 
			
		||||
function serverHandle( server, request, response, rHandle )
 | 
			
		||||
{
 | 
			
		||||
	var d = domain.create();
 | 
			
		||||
		var _self = this;
 | 
			
		||||
 | 
			
		||||
	d.addListener( 'error', function( e ) {
 | 
			
		||||
		Dragonfly.Error( e.stack );
 | 
			
		||||
		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( function()
 | 
			
		||||
			{
 | 
			
		||||
				process.exit(1);
 | 
			
		||||
			}, 3000);
 | 
			
		||||
			var killtimer = setTimeout( () => process.exit(1), 3000 );
 | 
			
		||||
			killtimer.unref();
 | 
			
		||||
 | 
			
		||||
			server.close();
 | 
			
		||||
			this.server.close();
 | 
			
		||||
 | 
			
		||||
			global.X_SERVER_CLUSTER.worker.destroy();
 | 
			
		||||
 | 
			
		||||
			server500( response, e );
 | 
			
		||||
			// 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 );
 | 
			
		||||
			process.exit();
 | 
			
		||||
		}
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	d.add( request );
 | 
			
		||||
	d.add( response );
 | 
			
		||||
 | 
			
		||||
	d.run( function() {
 | 
			
		||||
		rHandle( request, response );
 | 
			
		||||
	});
 | 
			
		||||
		finally
 | 
			
		||||
		{
 | 
			
		||||
			cluster.worker.disconnect();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Construncor
 | 
			
		||||
function AppDomain( handler, port, cluster )
 | 
			
		||||
module.exports = function( handler, port )
 | 
			
		||||
{
 | 
			
		||||
	var http = require( "http" );
 | 
			
		||||
	var server = http.createServer(
 | 
			
		||||
		function(req, res) {
 | 
			
		||||
	if( cluster.isMaster )
 | 
			
		||||
	{
 | 
			
		||||
		Dragonfly.Debug( "Not Listening on master" );
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var server = null;
 | 
			
		||||
 | 
			
		||||
	server = http.createServer(
 | 
			
		||||
		function( req, res )
 | 
			
		||||
		{
 | 
			
		||||
			res._hrtime = process.hrtime.bigint();
 | 
			
		||||
			serverHandle( server, req, res, handler );
 | 
			
		||||
			new Serving( server, handler, req, res );
 | 
			
		||||
		}
 | 
			
		||||
	);
 | 
			
		||||
 | 
			
		||||
	server.listen( port );
 | 
			
		||||
	Dragonfly.Info( "Listening on: " + port, Dragonfly.Visibility.VISIBLE );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
module.exports = AppDomain;
 | 
			
		||||
	return server;
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										10
									
								
								net/Http.js
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								net/Http.js
									
									
									
									
									
								
							@@ -30,6 +30,16 @@ class CResponse
 | 
			
		||||
 | 
			
		||||
			this.raw.writeHead( this.statusCode, this.headers );
 | 
			
		||||
			this.raw.end( this.content );
 | 
			
		||||
 | 
			
		||||
			if( this.raw._rejection )
 | 
			
		||||
			{
 | 
			
		||||
				process.removeListener( "unhandledRejection", this.raw._rejection );
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if( this.raw._uncaught )
 | 
			
		||||
			{
 | 
			
		||||
				process.removeListener( "uncaughtException", this.raw._uncaught );
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -57,7 +57,7 @@ class HttpRequest extends EventEmitter
 | 
			
		||||
	{
 | 
			
		||||
		this.Method = "POST";
 | 
			
		||||
		this.Headers[ "Content-Type" ] = "application/x-www-form-urlencoded";
 | 
			
		||||
		this.RawPostData = Data == undefined ? new Buffer([]) : new Buffer( Data );
 | 
			
		||||
		this.RawPostData = Data == undefined ? Buffer.alloc( 0 ) : Buffer.from( Data );
 | 
			
		||||
		this.Headers[ "Content-Length" ] = this.RawPostData.length;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -88,7 +88,7 @@ class HttpRequest extends EventEmitter
 | 
			
		||||
 | 
			
		||||
	OnResponseReceived( Response )
 | 
			
		||||
	{
 | 
			
		||||
		var ResponseData = new Buffer( 0 );
 | 
			
		||||
		var ResponseData = Buffer.alloc( 0 );
 | 
			
		||||
 | 
			
		||||
		Response.addListener( "data", 
 | 
			
		||||
			Data => ResponseData = Buffer.concat([ ResponseData, Data ])
 | 
			
		||||
 
 | 
			
		||||
@@ -75,7 +75,7 @@ class PostFrame extends EventEmitter
 | 
			
		||||
			{
 | 
			
		||||
				if( !( this.result instanceof Buffer ) )
 | 
			
		||||
				{
 | 
			
		||||
					this.result = new Buffer( this.result + "" );
 | 
			
		||||
					this.result = Buffer.from( this.result + "" );
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				this.HTTP.response.headers["Content-Length"] = this.result.length;
 | 
			
		||||
 
 | 
			
		||||
@@ -129,7 +129,7 @@ class WebFrame
 | 
			
		||||
		{
 | 
			
		||||
			if( !( this.result instanceof Buffer ) )
 | 
			
		||||
			{
 | 
			
		||||
				this.result = new Buffer( this.result + "" );
 | 
			
		||||
				this.result = Buffer.from( this.result + "" );
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			var acceptEncoding = this.HTTP.request.headers[ "accept-encoding" ] || "";
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,7 @@ class HttpRequestComplete extends EventArgs
 | 
			
		||||
		if( ResponseData === undefined )
 | 
			
		||||
		{
 | 
			
		||||
			this.statusCode = -1;
 | 
			
		||||
			this.Data = new Buffer( 0 );
 | 
			
		||||
			this.Data = Buffer.alloc( 0 );
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user