267 lines
		
	
	
		
			8.5 KiB
		
	
	
	
		
			Haxe
		
	
	
	
	
	
		
		
			
		
	
	
			267 lines
		
	
	
		
			8.5 KiB
		
	
	
	
		
			Haxe
		
	
	
	
	
	
|  | /* | ||
|  |  * Copyright (C)2014-2020 Haxe Foundation | ||
|  |  * | ||
|  |  * Permission is hereby granted, free of charge, to any person obtaining a | ||
|  |  * copy of this software and associated documentation files (the "Software"), | ||
|  |  * to deal in the Software without restriction, including without limitation | ||
|  |  * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
|  |  * and/or sell copies of the Software, and to permit persons to whom the | ||
|  |  * Software is furnished to do so, subject to the following conditions: | ||
|  |  * | ||
|  |  * The above copyright notice and this permission notice shall be included in | ||
|  |  * all copies or substantial portions of the Software. | ||
|  |  * | ||
|  |  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
|  |  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
|  |  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
|  |  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
|  |  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
|  |  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
|  |  * DEALINGS IN THE SOFTWARE. | ||
|  |  */ | ||
|  | 
 | ||
|  | package js.node; | ||
|  | 
 | ||
|  | import haxe.DynamicAccess; | ||
|  | import js.node.cluster.Worker; | ||
|  | import js.node.events.EventEmitter; | ||
|  | 
 | ||
|  | @:enum abstract ClusterEvent<T:haxe.Constraints.Function>(Event<T>) to Event<T> { | ||
|  | 	/** | ||
|  | 		When a new worker is forked the cluster module will emit a 'fork' event. | ||
|  | 		This can be used to log worker activity, and create your own timeout. | ||
|  | 
 | ||
|  | 		Listener arguments: | ||
|  | 			* worker:Worker | ||
|  | 	**/ | ||
|  | 	var Fork:ClusterEvent<Worker->Void> = "fork"; | ||
|  | 
 | ||
|  | 	/** | ||
|  | 		After forking a new worker, the worker should respond with an online message. | ||
|  | 		When the master receives an online message it will emit this event. | ||
|  | 
 | ||
|  | 		The difference between 'fork' and 'online' is that fork is emitted when the master forks a worker, | ||
|  | 		and 'online' is emitted when the worker is running. | ||
|  | 
 | ||
|  | 		Listener arguments: | ||
|  | 			* worker:Worker | ||
|  | 	**/ | ||
|  | 	var Online:ClusterEvent<Worker->Void> = "online"; | ||
|  | 
 | ||
|  | 	/** | ||
|  | 		After calling `listen` from a worker, when the 'listening' event is emitted on the server, | ||
|  | 		a listening event will also be emitted on cluster in the master. | ||
|  | 
 | ||
|  | 		The event handler is executed with two arguments, the `worker` contains the worker object and | ||
|  | 		the `address` object contains the following connection properties: address, port and addressType. | ||
|  | 		This is very useful if the worker is listening on more than one address. | ||
|  | 
 | ||
|  | 		 		Listener arguments: | ||
|  | 			* worker:Worker | ||
|  | 			* address:ListeningEventAddress | ||
|  | 	**/ | ||
|  | 	var Listening:ClusterEvent<Worker->ListeningEventAddress->Void> = "listening"; | ||
|  | 
 | ||
|  | 	/** | ||
|  | 		Emitted after the worker IPC channel has disconnected. | ||
|  | 
 | ||
|  | 		This can occur when a worker exits gracefully, is killed, | ||
|  | 		or is disconnected manually (such as with `Worker.disconnect`). | ||
|  | 
 | ||
|  | 		There may be a delay between the 'disconnect' and 'exit' events. | ||
|  | 
 | ||
|  | 		These events can be used to detect if the process is stuck in a cleanup | ||
|  | 		or if there are long-living connections. | ||
|  | 
 | ||
|  | 		Listener arguments: | ||
|  | 			* worker:Worker | ||
|  | 	**/ | ||
|  | 	var Disconnect:ClusterEvent<Worker->Void> = "disconnect"; | ||
|  | 
 | ||
|  | 	/** | ||
|  | 		When any of the workers die the cluster module will emit the 'exit' event. | ||
|  | 		This can be used to restart the worker by calling `Cluster.fork` again. | ||
|  | 
 | ||
|  | 		Listener arguments: | ||
|  | 			* worker:Worker | ||
|  | 			* code:Int - the exit code, if it exited normally. | ||
|  | 			* signal:String - the name of the signal (eg. 'SIGHUP') that caused the process to be killed. | ||
|  | 	**/ | ||
|  | 	var Exit:ClusterEvent<Worker->Int->String->Void> = "exit"; | ||
|  | 
 | ||
|  | 	/** | ||
|  | 		Emitted the first time that `Cluster.setupMaster` is called. | ||
|  | 	**/ | ||
|  | 	var Setup:ClusterEvent<ClusterSettings->Void> = "setup"; | ||
|  | } | ||
|  | 
 | ||
|  | /** | ||
|  | 	Structure emitted by 'listening' event. | ||
|  | **/ | ||
|  | typedef ListeningEventAddress = { | ||
|  | 	var address:String; | ||
|  | 	var port:Int; | ||
|  | 	var addressType:ListeningEventAddressType; | ||
|  | } | ||
|  | 
 | ||
|  | @:enum abstract ListeningEventAddressType(haxe.extern.EitherType<Int, String>) to haxe.extern.EitherType<Int, String> { | ||
|  | 	var TCPv4 = 4; | ||
|  | 	var TCPv6 = 6; | ||
|  | 	var Unix = -1; | ||
|  | 	var UDPv4 = "udp4"; | ||
|  | 	var UDPv6 = "udp6"; | ||
|  | } | ||
|  | 
 | ||
|  | @:jsRequire("cluster") | ||
|  | @:enum extern abstract ClusterSchedulingPolicy(Int) { | ||
|  | 	var SCHED_NONE; | ||
|  | 	var SCHED_RR; | ||
|  | } | ||
|  | 
 | ||
|  | /** | ||
|  | 	A single instance of Node runs in a single thread. | ||
|  | 	To take advantage of multi-core systems the user will sometimes want to launch a cluster of Node processes to handle the load. | ||
|  | 	The cluster module allows you to easily create child processes that all share server ports. | ||
|  | 
 | ||
|  | 	This feature was introduced recently, and may change in future versions. Please try it out and provide feedback. | ||
|  | 
 | ||
|  | 	Also note that, on Windows, it is not yet possible to set up a named pipe server in a worker. | ||
|  | **/ | ||
|  | @:jsRequire("cluster") | ||
|  | extern class Cluster extends EventEmitter<Cluster> { | ||
|  | 	/** | ||
|  | 		A reference to the `Cluster` object returned by node.js module. | ||
|  | 
 | ||
|  | 		It can be imported into module namespace by using: "import js.node.Cluster.instance in cluster" | ||
|  | 	**/ | ||
|  | 	public static inline var instance:Cluster = cast Cluster; | ||
|  | 
 | ||
|  | 	/** | ||
|  | 		The scheduling policy, either `SCHED_RR` for round-robin | ||
|  | 		or `SCHED_NONE` to leave it to the operating system. | ||
|  | 
 | ||
|  | 		This is a global setting and effectively frozen once you spawn the first worker | ||
|  | 		or call `setupMaster`, whatever comes first. | ||
|  | 
 | ||
|  | 		`SCHED_RR` is the default on all operating systems except Windows. | ||
|  | 		Windows will change to `SCHED_RR` once libuv is able to effectively distribute IOCP handles | ||
|  | 		without incurring a large performance hit. | ||
|  | 
 | ||
|  | 		`schedulingPolicy` can also be set through the NODE_CLUSTER_SCHED_POLICY environment variable. | ||
|  | 		Valid values are "rr" and "none". | ||
|  | 	**/ | ||
|  | 	var schedulingPolicy:ClusterSchedulingPolicy; | ||
|  | 
 | ||
|  | 	/** | ||
|  | 		After calling `setupMaster` (or `fork`) this settings object will contain the settings, including the default values. | ||
|  | 
 | ||
|  | 		It is effectively frozen after being set, because `setupMaster` can only be called once. | ||
|  | 
 | ||
|  | 		This object is not supposed to be changed or set manually, by you. | ||
|  | 	**/ | ||
|  | 	var settings(default, null):ClusterSettings; | ||
|  | 
 | ||
|  | 	/** | ||
|  | 		True if the process is a master. | ||
|  | 		This is determined by the process.env.NODE_UNIQUE_ID. | ||
|  | 		If process.env.NODE_UNIQUE_ID is undefined, then `isMaster` is true. | ||
|  | 	**/ | ||
|  | 	var isMaster(default, null):Bool; | ||
|  | 
 | ||
|  | 	/** | ||
|  | 		True if the process is not a master (it is the negation of `isMaster`). | ||
|  | 	**/ | ||
|  | 	var isWorker(default, null):Bool; | ||
|  | 
 | ||
|  | 	/** | ||
|  | 		`setupMaster` is used to change the default `fork` behavior. | ||
|  | 
 | ||
|  | 		Once called, the `settings` will be present in `settings`. | ||
|  | 
 | ||
|  | 		Note that: | ||
|  | 			Only the first call to `setupMaster` has any effect, subsequent calls are ignored | ||
|  | 
 | ||
|  | 			That because of the above, the only attribute of a worker that may be customized per-worker | ||
|  | 			is the `env` passed to `fork` | ||
|  | 
 | ||
|  | 			`fork` calls `setupMaster` internally to establish the defaults, so to have any effect, | ||
|  | 			`setupMaster` must be called before any calls to `fork` | ||
|  | 	**/ | ||
|  | 	function setupMaster(?settings:{?exec:String, ?args:Array<String>, ?silent:Bool}):Void; | ||
|  | 
 | ||
|  | 	/** | ||
|  | 		Spawn a new worker process. | ||
|  | 
 | ||
|  | 		This can only be called from the master process. | ||
|  | 	**/ | ||
|  | 	function fork(?env:DynamicAccess<String>):Worker; | ||
|  | 
 | ||
|  | 	/** | ||
|  | 		Calls `disconnect` on each worker in `workers`. | ||
|  | 
 | ||
|  | 		When they are disconnected all internal handles will be closed, | ||
|  | 		allowing the master process to die gracefully if no other event is waiting. | ||
|  | 
 | ||
|  | 		The method takes an optional `callback` argument which will be called when finished. | ||
|  | 
 | ||
|  | 		This can only be called from the master process. | ||
|  | 	**/ | ||
|  | 	function disconnect(?callback:Void->Void):Void; | ||
|  | 
 | ||
|  | 	/** | ||
|  | 		A reference to the current worker object. | ||
|  | 
 | ||
|  | 		Not available in the master process. | ||
|  | 	**/ | ||
|  | 	var worker(default, null):Worker; | ||
|  | 
 | ||
|  | 	/** | ||
|  | 		A hash that stores the active worker objects, keyed by `id` field. | ||
|  | 		Makes it easy to loop through all the workers. | ||
|  | 
 | ||
|  | 		It is only available in the master process. | ||
|  | 
 | ||
|  | 		A worker is removed from `workers` just before the 'disconnect' or 'exit' event is emitted. | ||
|  | 
 | ||
|  | 		Should you wish to reference a worker over a communication channel, using the worker's unique `id`
 | ||
|  | 		is the easiest way to find the worker. | ||
|  | 	**/ | ||
|  | 	var workers(default, null):DynamicAccess<Worker>; | ||
|  | } | ||
|  | 
 | ||
|  | typedef ClusterSettings = { | ||
|  | 	/** | ||
|  | 		list of string arguments passed to the node executable. | ||
|  | 		Default: process.execArgv | ||
|  | 	**/ | ||
|  | 	@:optional var execArgv(default, null):Array<String>; | ||
|  | 
 | ||
|  | 	/** | ||
|  | 		file path to worker file. | ||
|  | 		Default: process.argv[1] | ||
|  | 	**/ | ||
|  | 	@:optional var exec(default, null):String; | ||
|  | 
 | ||
|  | 	/** | ||
|  | 		string arguments passed to worker. | ||
|  | 		Default: process.argv.slice(2) | ||
|  | 	**/ | ||
|  | 	@:optional var args(default, null):Array<String>; | ||
|  | 
 | ||
|  | 	/** | ||
|  | 		whether or not to send output to parent's stdio.
 | ||
|  | 		Default: false | ||
|  | 	**/ | ||
|  | 	@:optional var silent(default, null):Bool; | ||
|  | 
 | ||
|  | 	/** | ||
|  | 		Sets the user identity of the process. | ||
|  | 	**/ | ||
|  | 	@:optional var uid(default, null):Int; | ||
|  | 
 | ||
|  | 	/** | ||
|  | 		Sets the group identity of the process. | ||
|  | 	**/ | ||
|  | 	@:optional var gid(default, null):Int; | ||
|  | } |