Compare commits
	
		
			2 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 4ad7b03117 | ||
|  | 7afd97737c | 
							
								
								
									
										20
									
								
								master.js
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								master.js
									
									
									
									
									
								
							| @ -30,24 +30,21 @@ function setup(opts) { | |||||||
|   var crypto = require('crypto'); |   var crypto = require('crypto'); | ||||||
|   var methods = getMethods(opts.instance, opts.methods); |   var methods = getMethods(opts.instance, opts.methods); | ||||||
|   var token = crypto.randomBytes(16).toString('hex'); |   var token = crypto.randomBytes(16).toString('hex'); | ||||||
|   var msgPrefix = 'cluster-rpc.' + opts.name; |  | ||||||
|   var rpcPrefix = msgPrefix + '.rpc'; |  | ||||||
|   var resultPrefix = msgPrefix + '.result'; |  | ||||||
|   var initPrefix = msgPrefix + '.init'; |  | ||||||
|   var inst = opts.instance; |   var inst = opts.instance; | ||||||
|  |   var prefixes = require('./prefixes.js').create(opts); // uses opts.name
 | ||||||
| 
 | 
 | ||||||
|   opts.master = opts.master || require('./process/master').create(); |   opts.master = opts.master || require('./process/master').create(prefixes); | ||||||
| 
 | 
 | ||||||
|   opts.master.on('connection', function (w) { |   opts.master.on('connection', function (w) { | ||||||
|     //console.log('debug w: worker connection');
 |     if (opts.debug) { console.log('[cluster-rpc] [master] worker connected'); } | ||||||
|     w.send({ |     w.send({ | ||||||
|       methods: methods |       methods: methods | ||||||
|     , _token: token |     , _token: token | ||||||
|     , type: initPrefix |     , type: prefixes.init | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     w.on('message', function (cmd) { |     w.on('message', function (cmd) { | ||||||
|       if (0 !== (cmd.type||'').indexOf(msgPrefix)) { |       if (0 !== (cmd.type||'').indexOf(prefixes.root)) { | ||||||
|         //console.log('debug w: got unknown message type');
 |         //console.log('debug w: got unknown message type');
 | ||||||
|         return; |         return; | ||||||
|       } |       } | ||||||
| @ -62,7 +59,7 @@ function setup(opts) { | |||||||
|       } |       } | ||||||
| 
 | 
 | ||||||
|       switch (cmd.type) { |       switch (cmd.type) { | ||||||
|         case rpcPrefix: |         case prefixes.rpc: | ||||||
|           cmd.args.push(function callback() { |           cmd.args.push(function callback() { | ||||||
|             // args is probably err, data in most cases
 |             // args is probably err, data in most cases
 | ||||||
|             var args = Array.prototype.slice.call(arguments); |             var args = Array.prototype.slice.call(arguments); | ||||||
| @ -72,7 +69,7 @@ function setup(opts) { | |||||||
|             , id: cmd.id |             , id: cmd.id | ||||||
|             //, this: this
 |             //, this: this
 | ||||||
|             , _token: token |             , _token: token | ||||||
|             , type: resultPrefix |             , type: prefixes.result | ||||||
|             }); |             }); | ||||||
|           }); |           }); | ||||||
| 
 | 
 | ||||||
| @ -89,12 +86,14 @@ function setup(opts) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| module.exports.create = function (opts) { | module.exports.create = function (opts) { | ||||||
|  |   if (opts.debug) { console.log('[cluster-rpc] [master] create'); } | ||||||
|   var cluster = require('cluster'); |   var cluster = require('cluster'); | ||||||
|   var PromiseA = opts.PromiseA || global.Promise || require('bluebird'); |   var PromiseA = opts.PromiseA || global.Promise || require('bluebird'); | ||||||
|   var init = false; |   var init = false; | ||||||
| 
 | 
 | ||||||
|   opts._promise = PromiseA.resolve(opts.instance); |   opts._promise = PromiseA.resolve(opts.instance); | ||||||
|   opts._promise.addWorker = function (w) { |   opts._promise.addWorker = function (w) { | ||||||
|  |     if (opts.debug) { console.log('[cluster-rpc] [master] addWorker wrapper'); } | ||||||
|     if (!init) { |     if (!init) { | ||||||
|       init = true; |       init = true; | ||||||
|       setup(opts); |       setup(opts); | ||||||
| @ -103,6 +102,7 @@ module.exports.create = function (opts) { | |||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   if (false !== opts.addOnFork) { |   if (false !== opts.addOnFork) { | ||||||
|  |     if (opts.debug) { console.log('[cluster-rpc] [master] -- will call addWorker on each fork'); } | ||||||
|     cluster.on('fork', opts._promise.addWorker); |     cluster.on('fork', opts._promise.addWorker); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										10
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								package.json
									
									
									
									
									
								
							| @ -1,14 +1,15 @@ | |||||||
| { | { | ||||||
|   "name": "cluster-rpc", |   "name": "cluster-rpc", | ||||||
|   "version": "1.0.4", |   "version": "1.0.7", | ||||||
|   "description": "A simple way to wrap a single-instance module to enable it to work with node cluster.", |   "description": "A simple way to wrap a single-instance module to enable it to work with node cluster.", | ||||||
|  |   "homepage": "https://git.coolaj86.com/coolaj86/cluster-rpc.js", | ||||||
|   "main": "index.js", |   "main": "index.js", | ||||||
|   "scripts": { |   "scripts": { | ||||||
|     "test": "node test.js" |     "test": "node test.js" | ||||||
|   }, |   }, | ||||||
|   "repository": { |   "repository": { | ||||||
|     "type": "git", |     "type": "git", | ||||||
|     "url": "git+ssh://git@github.com/coolaj86/cluster-rpc.git" |     "url": "git+https://git.coolaj86.com/coolaj86/cluster-rpc.js.git" | ||||||
|   }, |   }, | ||||||
|   "keywords": [ |   "keywords": [ | ||||||
|     "cluster", |     "cluster", | ||||||
| @ -17,7 +18,6 @@ | |||||||
|   "author": "AJ ONeal <coolaj86@gmail.com> (https://coolaj86.com/)", |   "author": "AJ ONeal <coolaj86@gmail.com> (https://coolaj86.com/)", | ||||||
|   "license": "(MIT OR Apache-2.0)", |   "license": "(MIT OR Apache-2.0)", | ||||||
|   "bugs": { |   "bugs": { | ||||||
|     "url": "https://github.com/coolaj86/cluster-rpc/issues" |     "url": "https://git.coolaj86.com/coolaj86/cluster-rpc.js/issues" | ||||||
|   }, |   } | ||||||
|   "homepage": "https://github.com/coolaj86/cluster-rpc#readme" |  | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										18
									
								
								prefixes.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								prefixes.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,18 @@ | |||||||
|  | 'use strict'; | ||||||
|  | 
 | ||||||
|  | module.exports.create = function (opts) { | ||||||
|  |   //var msgPrefix = 'cluster-rpc.' + opts.name;
 | ||||||
|  |   //var rpcPrefix = msgPrefix + '.rpc';
 | ||||||
|  |   //var resultPrefix = msgPrefix + '.result';
 | ||||||
|  |   //var initPrefix = msgPrefix + '.init';
 | ||||||
|  |   var root = 'com.daplie.cluster-rpc.' + (opts.name ? opts.name + '.' : ''); | ||||||
|  |   return { | ||||||
|  |     root: root | ||||||
|  |   , rpc: root + 'rpc' | ||||||
|  |   , result: root + 'result' | ||||||
|  |   , init: root + 'init' | ||||||
|  |   , connect: root + 'connect' | ||||||
|  |     // TODO the things that are using this should probably accept opts
 | ||||||
|  |   , debug: opts.debug | ||||||
|  |   }; | ||||||
|  | }; | ||||||
| @ -1,27 +1,45 @@ | |||||||
| 'use strict'; | 'use strict'; | ||||||
| 
 | 
 | ||||||
| module.exports.create = function () { | module.exports.create = function (prefixes) { | ||||||
|  |   if (prefixes.debug) { console.log('[cluster-rpc] master created'); } | ||||||
|   var m = new (require('events').EventEmitter)(); |   var m = new (require('events').EventEmitter)(); | ||||||
| 
 | 
 | ||||||
|   m.addWorker = function (worker) { |   m.addWorker = function (worker) { | ||||||
|  |     if (prefixes.debug) { console.log('[cluster-rpc] [master] adding worker'); } | ||||||
|     m._workers = []; |     m._workers = []; | ||||||
| 
 | 
 | ||||||
|     var w = new (require('events').EventEmitter)(); |     var w = new (require('events').EventEmitter)(); | ||||||
| 
 | 
 | ||||||
|     worker.on('online', function () { |     function emitConnection() { | ||||||
|       //console.log('debug mw: worker is up')
 |       if (w.__online) { | ||||||
|  |         return; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       w.__online = true; | ||||||
|       m.emit('connection', w); |       m.emit('connection', w); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     worker.on('online', function () { | ||||||
|  |       if (prefixes.debug) { console.log('[cluster-rpc] [master] worker came online, at fork'); } | ||||||
|  |       emitConnection(); | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     worker.on('message', function (data) { |     worker.on('message', function (data) { | ||||||
|       //console.log('debug mw: worker sends message', data)
 |       if (prefixes.connect === data.type) { | ||||||
|  |         if (prefixes.debug) { console.log('[cluster-rpc] [master] worker connected, manually'); } | ||||||
|  |         emitConnection(); | ||||||
|  |         return; | ||||||
|  |       } | ||||||
|  |       if (prefixes.debug) { console.log('[cluster-rpc] [master] worker sent message', data); } | ||||||
|       w.emit('message', data); |       w.emit('message', data); | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     w.send = function (data) { |     w.send = function (data) { | ||||||
|  |       if (prefixes.debug) { console.log('[cluster-rpc] [master] sending', data); } | ||||||
|       worker.send(data); |       worker.send(data); | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|  |     // TODO remove workers that exit
 | ||||||
|     m._workers.push(w); |     m._workers.push(w); | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,6 +1,7 @@ | |||||||
| 'use strict'; | 'use strict'; | ||||||
| 
 | 
 | ||||||
| module.exports.create = function (process) { | module.exports.create = function (process, prefixes) { | ||||||
|  |   if (prefixes.debug) { console.log('[cluster-rpc] worker created'); } | ||||||
|   var w = new (require('events').EventEmitter)(); |   var w = new (require('events').EventEmitter)(); | ||||||
| 
 | 
 | ||||||
|   process.on('message', function (data) { |   process.on('message', function (data) { | ||||||
| @ -11,5 +12,10 @@ module.exports.create = function (process) { | |||||||
|     process.send(data); |     process.send(data); | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|  |   // if this were a web / unix socket there would be a 'connection' event
 | ||||||
|  |   // emulating this is useful since the worker may create its cluster rpc
 | ||||||
|  |   // at any time, (which means it may miss the 'fork' event)
 | ||||||
|  |   w.send({ type: prefixes.connect }); | ||||||
|  | 
 | ||||||
|   return w; |   return w; | ||||||
| }; | }; | ||||||
|  | |||||||
							
								
								
									
										35
									
								
								test.js
									
									
									
									
									
								
							
							
						
						
									
										35
									
								
								test.js
									
									
									
									
									
								
							| @ -2,19 +2,18 @@ | |||||||
| 
 | 
 | ||||||
| var cluster = require('cluster'); | var cluster = require('cluster'); | ||||||
| var crpc; | var crpc; | ||||||
| var db = { |  | ||||||
|   get: function (key, cb) { |  | ||||||
|     cb(null, db[key]); |  | ||||||
|   } |  | ||||||
| , put: function (key, val, cb) { |  | ||||||
|     db[key] = val; |  | ||||||
|     cb(null); |  | ||||||
|   } |  | ||||||
| }; |  | ||||||
| 
 | 
 | ||||||
|  | function runMaster() { | ||||||
| 
 | 
 | ||||||
| if (cluster.isMaster) { |   var db = { | ||||||
| 
 |     get: function (key, cb) { | ||||||
|  |       cb(null, db[key]); | ||||||
|  |     } | ||||||
|  |   , put: function (key, val, cb) { | ||||||
|  |       db[key] = val; | ||||||
|  |       if (cb) { cb(null); } | ||||||
|  |     } | ||||||
|  |   }; | ||||||
| 
 | 
 | ||||||
|   crpc = require('./master').create({ |   crpc = require('./master').create({ | ||||||
|     instance: db |     instance: db | ||||||
| @ -26,10 +25,9 @@ if (cluster.isMaster) { | |||||||
|   }); |   }); | ||||||
|   cluster.fork(); |   cluster.fork(); | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| } | } | ||||||
| else { |  | ||||||
| 
 | 
 | ||||||
|  | function runWorker() { | ||||||
| 
 | 
 | ||||||
|   crpc = require('./worker').create({ |   crpc = require('./worker').create({ | ||||||
|     name: 'foo-level' |     name: 'foo-level' | ||||||
| @ -38,6 +36,17 @@ else { | |||||||
| 
 | 
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | if (cluster.isMaster) { | ||||||
|  | 
 | ||||||
|  |   runMaster(); | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | else { | ||||||
|  | 
 | ||||||
|  |   runWorker(); | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| crpc.then(function (db) { | crpc.then(function (db) { | ||||||
|   setTimeout(function () { |   setTimeout(function () { | ||||||
|  | |||||||
							
								
								
									
										22
									
								
								worker.js
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								worker.js
									
									
									
									
									
								
							| @ -9,11 +9,8 @@ module.exports.create = function (opts) { | |||||||
|   var crypto = require('crypto'); |   var crypto = require('crypto'); | ||||||
|   var token = null; |   var token = null; | ||||||
|   var inst = {}; |   var inst = {}; | ||||||
|   var ws = opts.worker = opts.worker || require('./process/worker').create(process); |   var prefixes = require('./prefixes.js').create(opts); | ||||||
|   var msgPrefix = 'cluster-rpc.' + opts.name; |   var ws = opts.worker = opts.worker || require('./process/worker').create(process, prefixes); | ||||||
|   var rpcPrefix = msgPrefix + '.rpc'; |  | ||||||
|   var resultPrefix = msgPrefix + '.result'; |  | ||||||
|   var initPrefix = msgPrefix + '.init'; |  | ||||||
| 
 | 
 | ||||||
|   ws.___listeners = []; |   ws.___listeners = []; | ||||||
| 
 | 
 | ||||||
| @ -30,7 +27,7 @@ module.exports.create = function (opts) { | |||||||
|       args: args |       args: args | ||||||
|     , func: fname |     , func: fname | ||||||
|     , id: id |     , id: id | ||||||
|     , type: rpcPrefix |     , type: prefixes.rpc | ||||||
|     , _token: token |     , _token: token | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
| @ -96,24 +93,21 @@ module.exports.create = function (opts) { | |||||||
| 
 | 
 | ||||||
|   return new PromiseA(function (resolve) { |   return new PromiseA(function (resolve) { | ||||||
|     ws.on('message', function (cmd) { |     ws.on('message', function (cmd) { | ||||||
|       //console.log('debug m: mesage', cmd);
 |       if (opts.debug) { console.log('[cluster-rpc] [worker] message received', cmd); } | ||||||
|       if (0 !== (cmd.type||'').indexOf(msgPrefix)) { | 
 | ||||||
|         //console.log('debug m: ignore msg', cmd);
 |       if (0 !== (cmd.type||'').indexOf(prefixes.root)) { | ||||||
|         //console.log(cmd.type, msgPrefix);
 |  | ||||||
|         //console.log(cmd.type.indexOf(msgPrefix));
 |  | ||||||
|         return; |         return; | ||||||
|       } |       } | ||||||
|       if (token && token !== cmd._token) { |       if (token && token !== cmd._token) { | ||||||
|         //console.log('debug m: ignore msg', cmd);
 |  | ||||||
|         return; |         return; | ||||||
|       } |       } | ||||||
| 
 | 
 | ||||||
|       switch (cmd.type) { |       switch (cmd.type) { | ||||||
|         case initPrefix: |         case prefixes.init: | ||||||
|           onInit(cmd); |           onInit(cmd); | ||||||
|           resolve(inst); |           resolve(inst); | ||||||
|           break; |           break; | ||||||
|         case resultPrefix: |         case prefixes.result: | ||||||
|           onResult(cmd); |           onResult(cmd); | ||||||
|           break; |           break; | ||||||
|         default: |         default: | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user