Commits

Benjamin Conlan committed 69cfccf

created faux process api

Comments (0)

Files changed (4)

 
 var jvmpin = require('jvmpin');
 
-jvmpin.createConnection(1234, 'localhost').spawn('your.main.Class');
+var proc = jvmpin.createConnection(1234, 'localhost').spawn('your.main.Class');
 
-```
+// now to take over the currently running context by binding stdio
+proc.stdout.pipe(process.stdout);
+proc.stderr.pipe(process.stderr);
+
+process.stdin.pipe(proc.stdin);
+proc.on('exit', function(c) { process.exit(); })
 
-This will bind the STDIO streams to the executing process. (something
-that is yet to be corrected).
+```
 
 For more information please consult the [API
 Documentation](https://bitbucket.org/foldr/jvmpin/raw/master/lib/jvmpin.js)
  * Copyright(c) 2012 Foldr
  * EPL Licensed
  */
-var util = require('util'),
-    net  = require('net');
+var util         = require('util'),
+    net          = require('net'),
+    events       = require('events'),
+    BufferStream = require('bufferstream');
 
 /**
  * createConnection([port], [host], [connectionCallback])
 	JVMPin.super_.apply(this, arguments);
 	
 	// The communication channel to the Nailgun JVM instance.
-	this._socket = socket
+	this._socket = socket;
 	
 	// Data events can be emitted without a complete chunk hence a simple buffer is used.
 	this._unprocessedBuffer = new Buffer(0);
 	};
 
 	/**
+	 * The JVMPinProcess is basically dumb terminal. It is used to perform stdio
+	 * redirection and propagate the appropriate signals for each. The API is akin
+	 * to that found in the 'child_process' API only that none of the overhead of
+	 * forking/executing/spawning occurs.
+	 *
+	 * @since 1.0.6
+	 */
+	function JVMPinProcess() {
+		JVMPin.super_.apply(this, arguments);
+
+		this.stdin = new BufferStream();
+		this.stdout = new BufferStream();
+		this.stderr = new BufferStream();
+
+		var self = this;
+
+		/**
+		 * A faux 'kill' function which emits the required signals to ensure that
+		 * all bound objects remove themselves as appropriate. For all intents and
+		 * purposes this should very much should be deemed a deconstructor.
+		 *
+		 * @param signal - Number. process exit code provided by the ng-server.
+		 */
+		this.kill = function(signal) {
+			signal = signal || 0;
+			self.emit('exit', signal);
+			self.stdin.emit('close')
+			self.stdin.disable();
+			self.stdout.emit('close')
+			self.stdout.disable();
+			self.stderr.emit('close')
+			self.stderr.disable();
+		}
+	}
+	util.inherits(JVMPinProcess, events.EventEmitter);
+
+	/**
 	 * readChunks(bufferData)
 	 *
 	 * Reads the passed in bufferData and processes any complete chunks. All unprocessed
 	/**
 	 * spawn(command, [args], [options])
 	 *
-	 * NOTE Currently this binds stdin/stdout/stderr to the currently executing process.
-	 *      This will eventually be changed soon and instead a child process will be bound.
-	 *
 	 * @param command - String. The 'nail' or main java class to execute.
 	 * @param args    - Array. A list of arguments to send the command. (empty by default)
 	 * @param options - Object A set of possible options to send to the process. Object keys
 
 		var args = args || []
 		    options = options || {},
+		    options.exitOnClose = options.exitOnClose || true;
 		    options.env = options.env || process.env,
 		    options.cwd = options.cwd || process.cwd();
 
 		self.writeChunk(self.CHUNK_TYPE.WORKING_DIRECTORY, options.cwd);
 		self.writeChunk(self.CHUNK_TYPE.COMMAND, command);
 
+		var jvmpin_process = new JVMPinProcess();
 		self._socket.on('data', function(data) {
 			var chunk = self.readChunks(data).forEach(function(chunk) {
 				switch (chunk.type) {
 					case self.CHUNK_TYPE.STDOUT:
-						process.stdout.write(chunk.data.toString());
+						jvmpin_process.stdout.write(chunk.data.toString());
 						break;
 					case self.CHUNK_TYPE.STDERR:
-						process.stderr.write(chunk.data.toString());
+						jvmpin_process.stderr.write(chunk.data.toString());
 						break;
 					case self.CHUNK_TYPE.EXIT:
-						console.log('process exit requested, exit code:', chunk.data.toString());
-						process.exit(chunk.data.toString());
+						jvmpin_process.kill(chunk.data.toString());
 						break;
 					default:
 						console.error("Unexpected chunk type", chunk.type, chunk.data.toString());
 				}
 			});
-		}).on('end', function() {
-			console.log('server closed connection');
-		}).on('close', function() {
-			console.log('connection closed');
 		});
 
-		// TODO: now bind io redirection
-		// return new JVMPinProcess().stdin -> jvmpin.inputBuffer
-		//            JVMPinProcess().stdin.eol -> jvmpin.sendInputbuffer.
-		//            JVMPinProcess().stderr <- jvmpin.message(Error(data));
-		//            JVMPinProcess().stdout <- jvmpin.message(data));
-		process.stdin.resume();
-		process.stdin.setEncoding('ascii');
-		process.stdin.on('data', function(data) {
+		jvmpin_process.stdin.on('data', function(data) {
 			self.writeChunk(self.CHUNK_TYPE.STDIN, data);
 		}).on('end', function() {
 			self.writeChunk(self.CHUNK_TYPE.EOF, "");
 		});
+
+		return jvmpin_process;
 	};
 }
-util.inherits(JVMPin, require('events').EventEmitter);
+util.inherits(JVMPin, events.EventEmitter);
 	"author": "Benjamin Conlan",
 	"name": "jvmpin",
 	"description": "Nailgun client",
-	"version": "1.0.5",
+	"version": "1.0.6",
 	"bugs": {
 		"url": "https://bitbucket.org/foldr/jvmpin/issues"
 	},
 		"type": "EPL",
 		"url": "http://opensource.org/licenses/EPL-1.0"
 	}],
+	"dependencies": {
+		"bufferstream": "~0.5"
+	},
 	"main": "lib/jvmpin",
 	"engines": {
 		"node": "~0.8"

test/jvmpin-test.js

  */
 var jvmpin = require('../lib/jvmpin');
 
-var process = jvmpin.createConnection().spawn('io.foldr.ngtesthost.Stdin');
+var client = jvmpin.createConnection();
+var proc = client.spawn('io.foldr.ngtesthost.Stdin');
+
+proc.stdout.pipe(process.stdout);
+proc.stderr.pipe(process.stderr);
+
+process.stdin.pipe(proc.stdin);
+proc.on('exit', function(c) { process.exit(); })
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.