2017-02-18 06:02:33 +03:00
|
|
|
/**********************************************************************
|
|
|
|
|
*
|
|
|
|
|
* Setup a node.js child_process communications channel and listen and
|
|
|
|
|
* exec commands...
|
|
|
|
|
*
|
|
|
|
|
*
|
|
|
|
|
**********************************************************************/
|
|
|
|
|
((typeof define)[0]=='u'?function(f){module.exports=f(require)}:define)
|
|
|
|
|
(function(require){ var module={} // make module AMD/node compatible...
|
|
|
|
|
/*********************************************************************/
|
|
|
|
|
|
|
|
|
|
var actions = require('lib/actions')
|
|
|
|
|
var features = require('lib/features')
|
|
|
|
|
|
|
|
|
|
var core = require('features/core')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2017-02-24 19:47:04 +03:00
|
|
|
/*********************************************************************/
|
|
|
|
|
// helpers...
|
|
|
|
|
|
|
|
|
|
// XXX should this parse out the protocol???
|
|
|
|
|
// ...technically we no longer need it....
|
|
|
|
|
var makeProtocolHandiler = function(protocol, func){
|
|
|
|
|
return function(id){
|
|
|
|
|
return id.startsWith(protocol + ':')
|
|
|
|
|
&& func.apply(this, arguments) } }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2017-02-18 06:02:33 +03:00
|
|
|
/*********************************************************************/
|
|
|
|
|
|
|
|
|
|
// XXX this is a generic API, add ability to define protocols...
|
|
|
|
|
// Protocols:
|
|
|
|
|
// - child_process
|
2017-02-22 17:49:31 +03:00
|
|
|
// - PeerJS
|
|
|
|
|
// - https
|
2017-02-22 17:46:40 +03:00
|
|
|
// - rpc (???)
|
|
|
|
|
// - mq (???)
|
2017-02-19 05:55:53 +03:00
|
|
|
// - ...
|
2017-02-22 17:47:49 +03:00
|
|
|
// XXX should this do "sync"???
|
|
|
|
|
// XXX should the couch api be implemented over this of independently???
|
2017-02-18 06:02:33 +03:00
|
|
|
var PeerActions = actions.Actions({
|
|
|
|
|
|
2017-02-20 04:27:09 +03:00
|
|
|
// Format:
|
|
|
|
|
// {
|
|
|
|
|
// <id>: <spec>,
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// XXX <spec> format???
|
|
|
|
|
// ...should flow from the protocol definition and architecture...
|
2017-02-22 17:05:12 +03:00
|
|
|
// XXX should url and id be the same thing???
|
2017-02-22 17:06:12 +03:00
|
|
|
// ...this might simplify things, and to make things pretty
|
|
|
|
|
// implementing aliases will do the trick...
|
2017-02-21 06:56:05 +03:00
|
|
|
// XXX Q: should peer adapter be a feature that defines/extnds a set
|
|
|
|
|
// of actions???
|
|
|
|
|
// ...e.g. base peerCreate(..) defines the protocol but does
|
|
|
|
|
// nothing, while each implementation checks if the url is
|
|
|
|
|
// compatible and handles it accordingly...
|
2017-02-20 04:27:09 +03:00
|
|
|
__peers: null,
|
|
|
|
|
|
2017-02-18 06:02:33 +03:00
|
|
|
// XXX need more control...
|
|
|
|
|
// - get proxies to specific peer...
|
|
|
|
|
get peeractions(){
|
|
|
|
|
return this.getPeerActions() },
|
|
|
|
|
|
|
|
|
|
getPeerActions: ['- Peer/',
|
|
|
|
|
function(id){
|
2017-02-19 05:55:53 +03:00
|
|
|
var that = this
|
|
|
|
|
return this.actions.filter(id ?
|
|
|
|
|
function(action){
|
|
|
|
|
return that.getActionAttr(action, '__peer__') == id }
|
|
|
|
|
// get all peer actions...
|
|
|
|
|
: function(action){
|
|
|
|
|
return that.getActionAttr(action, '__peer__') })
|
2017-02-18 06:02:33 +03:00
|
|
|
}],
|
2017-02-19 05:55:53 +03:00
|
|
|
// XXX should this also check props???
|
|
|
|
|
isPeerAction: ['- Peer/',
|
|
|
|
|
function(name){
|
|
|
|
|
return !!this.getActionAttr(name, '__peer__') }],
|
2017-02-18 06:02:33 +03:00
|
|
|
|
2017-02-22 04:59:47 +03:00
|
|
|
//
|
2017-02-22 05:07:07 +03:00
|
|
|
// NOTE: it is the responsibility of the overloading action to trigger
|
|
|
|
|
// the appropriate events...
|
2017-02-22 04:59:47 +03:00
|
|
|
//
|
|
|
|
|
// XXX should this be sync or async???
|
2017-02-22 04:54:31 +03:00
|
|
|
// XXX this should create or connect to a peer depending on protocol...
|
2017-02-22 04:59:47 +03:00
|
|
|
// XXX the events should get called on the peer too -- who is
|
|
|
|
|
// responsible for this???
|
2017-02-22 04:54:31 +03:00
|
|
|
peerConnect: ['- Peer/',
|
2017-02-22 05:07:07 +03:00
|
|
|
function(id, options){ return id }],
|
2017-02-22 04:54:31 +03:00
|
|
|
peerDisconnect: ['- Peer/',
|
2017-02-22 05:07:07 +03:00
|
|
|
function(id){ }],
|
2017-02-18 06:02:33 +03:00
|
|
|
|
|
|
|
|
// event...
|
|
|
|
|
peerConnected: ['- Peer/',
|
2017-02-19 06:22:32 +03:00
|
|
|
core.notUserCallable(function(id){
|
2017-02-18 06:02:33 +03:00
|
|
|
// XXX
|
2017-02-19 05:55:53 +03:00
|
|
|
})],
|
2017-02-18 06:02:33 +03:00
|
|
|
// event...
|
|
|
|
|
peerDisconnected: ['- Peer/',
|
2017-02-19 06:22:32 +03:00
|
|
|
core.notUserCallable(function(id){
|
2017-02-18 06:02:33 +03:00
|
|
|
// XXX
|
2017-02-19 05:55:53 +03:00
|
|
|
})],
|
2017-02-18 06:02:33 +03:00
|
|
|
|
|
|
|
|
peerList: ['- Peer/',
|
2017-02-21 06:56:05 +03:00
|
|
|
function(){ return Object.keys(this.__peers || {}) }],
|
2017-02-22 04:54:31 +03:00
|
|
|
// XXX format spec!!!
|
2017-02-18 06:02:33 +03:00
|
|
|
peerSpec: ['- Peer/',
|
2017-02-19 06:22:32 +03:00
|
|
|
function(id){
|
2017-02-18 06:02:33 +03:00
|
|
|
// XXX
|
|
|
|
|
}],
|
|
|
|
|
peerProxy: ['- Peer/',
|
2017-02-19 06:22:32 +03:00
|
|
|
function(id){
|
2017-02-18 06:02:33 +03:00
|
|
|
// XXX
|
|
|
|
|
}],
|
|
|
|
|
|
2017-02-22 05:13:39 +03:00
|
|
|
// XXX how should we handler the return value?
|
2017-02-18 06:02:33 +03:00
|
|
|
peerCall: ['- Peer/',
|
2017-02-19 06:22:32 +03:00
|
|
|
function(id, action){
|
2017-02-18 06:02:33 +03:00
|
|
|
// XXX
|
|
|
|
|
}],
|
|
|
|
|
peerApply: ['- Peer/',
|
2017-02-19 06:22:32 +03:00
|
|
|
function(id, action, args){
|
2017-02-18 06:02:33 +03:00
|
|
|
// XXX
|
|
|
|
|
}],
|
|
|
|
|
|
|
|
|
|
// XXX if no actions are given, proxy all...
|
|
|
|
|
// XXX also proxy descriptors???
|
|
|
|
|
peerMixin: ['- Peer/',
|
|
|
|
|
function(id, actions){
|
2017-02-21 06:56:05 +03:00
|
|
|
var that = this
|
|
|
|
|
var spec = this.peerSpec(id)
|
2017-02-18 06:02:33 +03:00
|
|
|
// XXX
|
2017-02-21 06:56:05 +03:00
|
|
|
actions = actions || Object.keys(spec.actions)
|
|
|
|
|
actions.forEach(function(action){
|
|
|
|
|
if(that[action]){
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// XXX
|
|
|
|
|
var action_spec = []
|
|
|
|
|
|
|
|
|
|
that[action] = actions.Action(action, action_spec)
|
|
|
|
|
})
|
2017-02-18 06:02:33 +03:00
|
|
|
}],
|
|
|
|
|
// XXX should this be .peerMixout(..)
|
|
|
|
|
peerMixout: ['- Peer/',
|
|
|
|
|
function(id, actions){
|
|
|
|
|
// XXX
|
|
|
|
|
}],
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
var Peer =
|
|
|
|
|
module.Peer = core.ImageGridFeatures.Feature({
|
|
|
|
|
title: '',
|
|
|
|
|
doc: '',
|
|
|
|
|
|
2017-02-22 05:02:13 +03:00
|
|
|
tag: 'peer',
|
2017-02-18 06:02:33 +03:00
|
|
|
|
|
|
|
|
actions: PeerActions,
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2017-02-22 05:02:13 +03:00
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------
|
|
|
|
|
|
2017-02-24 19:47:04 +03:00
|
|
|
// XXX all the return values here will be ignored -- need a way to figure
|
|
|
|
|
// out a cooperative mechanic to return promises...
|
2017-02-22 05:02:13 +03:00
|
|
|
var ChildProcessPeerActions = actions.Actions({
|
2017-02-22 05:07:07 +03:00
|
|
|
peerConnect: ['- Peer/',
|
2017-02-24 19:47:04 +03:00
|
|
|
makeProtocolHandiler('child', function(id, options){
|
|
|
|
|
// XXX need a cooperative way to pass this to the root method return...
|
|
|
|
|
return new Promise((function(resolve, reject){
|
|
|
|
|
// already connected...
|
|
|
|
|
if(id in this.__peers){
|
|
|
|
|
return resolve(id)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// XXX run ig.js in child_process + add peer feature to setup...
|
|
|
|
|
// XXX
|
|
|
|
|
}).bind(this))
|
|
|
|
|
})],
|
2017-02-22 05:07:07 +03:00
|
|
|
peerDisconnect: ['- Peer/',
|
2017-02-24 19:47:04 +03:00
|
|
|
makeProtocolHandiler('child', function(id){
|
|
|
|
|
// XXX need a cooperative way to pass this to the root method return...
|
|
|
|
|
return new Promise((function(resolve, reject){
|
|
|
|
|
// already disconnected...
|
|
|
|
|
if(this.__peers[id] == null){
|
|
|
|
|
return resolve(id)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// trigger stop...
|
|
|
|
|
this.peerCall(id, 'stop')
|
|
|
|
|
.then(function(){
|
|
|
|
|
// XXX terminate child...
|
|
|
|
|
// XXX
|
|
|
|
|
})
|
|
|
|
|
}).bind(this))
|
|
|
|
|
})],
|
2017-02-22 05:07:07 +03:00
|
|
|
|
2017-02-22 05:10:50 +03:00
|
|
|
peerCall: ['- Peer/',
|
2017-02-24 19:47:04 +03:00
|
|
|
makeProtocolHandiler('child', function(id, action){
|
|
|
|
|
// XXX need a cooperative way to pass this to the root method return...
|
|
|
|
|
return new Promise((function(resolve, reject){
|
|
|
|
|
// XXX
|
|
|
|
|
}).bind(this))
|
|
|
|
|
})],
|
2017-02-22 05:10:50 +03:00
|
|
|
peerApply: ['- Peer/',
|
2017-02-24 19:47:04 +03:00
|
|
|
makeProtocolHandiler('child', function(id, action, args){
|
|
|
|
|
// XXX need a cooperative way to pass this to the root method return...
|
|
|
|
|
return new Promise((function(resolve, reject){
|
|
|
|
|
// XXX
|
|
|
|
|
}).bind(this))
|
|
|
|
|
})],
|
2017-02-22 05:02:13 +03:00
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var ChildProcessPeer =
|
|
|
|
|
module.ChildProcessPeer = core.ImageGridFeatures.Feature({
|
|
|
|
|
title: '',
|
|
|
|
|
doc: '',
|
|
|
|
|
|
|
|
|
|
tag: 'child-process-peer',
|
2017-02-22 05:10:50 +03:00
|
|
|
depends: [
|
|
|
|
|
'peer',
|
|
|
|
|
],
|
2017-02-22 05:02:13 +03:00
|
|
|
|
2017-02-24 19:47:04 +03:00
|
|
|
isApplicable: function(){
|
|
|
|
|
return this.runtime == 'nw' || this.runtime == 'node' },
|
|
|
|
|
|
2017-02-22 05:02:13 +03:00
|
|
|
actions: ChildProcessPeerActions,
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2017-02-18 06:02:33 +03:00
|
|
|
/**********************************************************************
|
|
|
|
|
* vim:set ts=4 sw=4 : */ return module })
|