Skip to content

Commit

Permalink
Merge pull request #107 from marshallswain/dynamic-services-2
Browse files Browse the repository at this point in the history
Dynamic services 2
  • Loading branch information
daffl committed Feb 11, 2015
2 parents 1573f72 + aeec8d9 commit d881599
Show file tree
Hide file tree
Showing 9 changed files with 563 additions and 84 deletions.
15 changes: 9 additions & 6 deletions lib/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,6 @@ module.exports = {
var protoService = Proto.extend(service);
var self = this;

if(this._setup) {
throw new Error('You can not register a service after app.setup() has been called.');
}

location = stripSlashes(location);

// Add all the mixins
Expand All @@ -49,8 +45,13 @@ module.exports = {
provider(location, protoService, options || {});
});

// If already _setup, just add this single service.
if (this._setup && this.addService) {
this.addService(protoService, stripSlashes(location));
}

this.services[location] = protoService;
return this;
return protoService;
},

use: function () {
Expand All @@ -68,10 +69,12 @@ module.exports = {
return this._super.apply(this, arguments);
}

return this.service(location, service, {
this.service(location, service, {
// Any arguments left over are other middleware that we want to pass to the providers
middleware: args
});

return this;
},

setup: function() {
Expand Down
9 changes: 5 additions & 4 deletions lib/mixins/event.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,16 @@ var eventMappings = {
*/
var EventMixin = {
setup: function () {
this.applyEvents();
return this._super ? this._super.apply(this, arguments) : this;
},
applyEvents:function(){
var emitter = this._rubberDuck = rubberduck.emitter(this);
var self = this;

self._serviceEvents = [];
// Pass the Rubberduck error event through

// Pass the Rubberduck error event through
// TODO deal with error events properly
emitter.on('error', function (errors) {
self.emit('serviceError', errors[0]);
Expand All @@ -45,9 +49,6 @@ var EventMixin = {
});
}
});


return this._super ? this._super.apply(this, arguments) : this;
}
};

Expand Down
26 changes: 23 additions & 3 deletions lib/providers/socket/commons.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use strict';

var _ = require('lodash');
var eventsMixin = require('../../mixins/event').Mixin;

// The position of the params parameters for a service method so that we can extend them
// default is 1
Expand All @@ -10,8 +11,19 @@ var paramsPositions = {
patch: 2
};

// Set up the service method handlers for a service and socket.
exports.setupMethodHandler = function setupMethodHandler (emitter, params, service, path, method) {
exports.addService = function addService(service, path){
// Add handlers for the service to connected sockets.
_.each(this.info.connections, function (spark) {
this.setupMethodHandlers(service, path, spark);
}, this);

// Setup events for the service.
eventsMixin.applyEvents.call(service);
exports.setupEventHandlers.call(this, service, path);
};

// Set up the service method handler for a service and socket.
exports.setupMethodHandler = function setupMethodHandler(emitter, params, service, path, method) {
var name = path + '::' + method;
var position = typeof paramsPositions[method] !== 'undefined' ? paramsPositions[method] : 1;

Expand All @@ -29,6 +41,15 @@ exports.setupMethodHandler = function setupMethodHandler (emitter, params, servi
}
};

exports.setupEventHandlers = function setupEventHandlers(service, path){
// If the service emits events that we want to listen to (Event mixin)
if (typeof service.on === 'function' && service._serviceEvents) {
_.each(service._serviceEvents, function (ev) {
exports.setupEventHandler(this.info, service, path, ev);
}, this);
}
};

// Set up event handlers for a given service and connected sockets.
// Send it through the service dispatching mechanism (`removed(data, params, callback)`,
// `updated(data, params, callback)` and `created(data, params, callback)`) if it
Expand All @@ -54,4 +75,3 @@ exports.setupEventHandler = function setupEventHandler (info, service, path, ev)
});
});
};

29 changes: 16 additions & 13 deletions lib/providers/socket/primus.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,42 +23,45 @@ module.exports = function(config, configurer) {
}

var primus = this.primus = new Primus(server, config);
var info = {
this.info = {
emitters: function() {
return primus;
},
params: function(spark) {
return spark.request.feathers;
},
method: 'send'
method: 'send',
connections: this.primus.connections
};

primus.use('emitter', Emitter);

// For a new connection, set up the service method handlers
primus.on('connection', function (spark) {
// Process services that were registered at startup.
_.each(self.services, function (service, path) {
_.each(self.methods, function (method) {
commons.setupMethodHandler(spark, spark.request.feathers, service, path, method);
});
self.setupMethodHandlers.call(self, service, path, spark);
});
});

// Set up events and event dispatching
_.each(self.services, function (service, path) {
// If the service emits events that we want to listen to (Event mixin)
if (typeof service.on === 'function' && service._serviceEvents) {
_.each(service._serviceEvents, function (ev) {
commons.setupEventHandler(info, service, path, ev);
});
}
});
_.each(this.services, function (service, path) {
commons.setupEventHandlers.call(this, service, path);
}, this);

if (typeof configurer === 'function') {
configurer.call(this, primus);
}

return result;
},

addService: commons.addService,

setupMethodHandlers: function(service, path, spark){
_.each(this.methods, function (method) {
commons.setupMethodHandler(spark, spark.request.feathers, service, path, method);
}, this);
}
}, app);
};
Expand Down
27 changes: 15 additions & 12 deletions lib/providers/socket/socketio.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,40 +23,43 @@ module.exports = function (config) {

var io = this.io = socketio.listen(server);
// The info object we can pass to commons.setupEventHandler
var info = {
this.info = {
emitters: function() {
return io.sockets.sockets;
},
params: function(socket) {
return socket.feathers;
},
method: 'emit'
method: 'emit',
connections: this.connections = this.io.sockets.connected
};

// For a new connection, set up the service method handlers
io.sockets.on('connection', function (socket) {
// Process services that were registered at startup.
_.each(self.services, function (service, path) {
_.each(self.methods, function (method) {
commons.setupMethodHandler(socket, socket.feathers || {}, service, path, method);
});
self.setupMethodHandlers.call(self, service, path, socket);
});
});

// Set up events and event dispatching
_.each(self.services, function (service, path) {
// If the service emits events that we want to listen to (Event mixin)
if (typeof service.on === 'function' && service._serviceEvents) {
_.each(service._serviceEvents, function (ev) {
commons.setupEventHandler(info, service, path, ev);
});
}
});
commons.setupEventHandlers.call(this, service, path);
}, this);

if (typeof config === 'function') {
config.call(this, io);
}

return result;
},

addService: commons.addService,

setupMethodHandlers: function(service, path, socket){
_.each(this.methods, function (method) {
commons.setupMethodHandler(socket, socket.feathers || {}, service, path, method);
}, this);
}
}, app);
};
Expand Down
Loading

0 comments on commit d881599

Please sign in to comment.