Skip to content

Commit

Permalink
Fix connectionless plugins. Closes #2817
Browse files Browse the repository at this point in the history
  • Loading branch information
hueniverse committed Oct 3, 2015
1 parent 990aad4 commit 5c6cef2
Show file tree
Hide file tree
Showing 5 changed files with 342 additions and 31 deletions.
8 changes: 6 additions & 2 deletions API.md
Original file line number Diff line number Diff line change
Expand Up @@ -866,7 +866,9 @@ Used within a plugin to declares a required dependency on other [plugins](#plugi
- `err` - internal error condition, which is returned back via the
[`server.start()`](#serverstartcallback) callback.

The `after` method is identical to setting a server extension point on `'onPreStart'`.
The `after` method is identical to setting a server extension point on `'onPreStart'`. Connectionless
plugins (those with `attributes.connections` set to `false`) can only depend on other connectionless
plugins (server initialization will fail even of the dependency is loaded but is not connectionless).

```js
exports.register = function (server, options, next) {
Expand Down Expand Up @@ -1383,7 +1385,9 @@ Registers a plugin where:
- `options` - optional registration options (different from the options passed to the registration
function):
- `once` - if `true`, the registration is skipped for any connection already registered with.
Cannot be used with plugin options. Defaults to `false`.
Cannot be used with plugin options. If the plugin does not have a `connections` attribute set
to `false` and the registration selection is empty, registration will be skipped as no connections
are available to register once. Defaults to `false`.
- `routes` - modifiers applied to each route added by the plugin:
- `prefix` - string added as prefix to any route path (must begin with `'/'`). If a plugin
registers a child plugin the `prefix` is passed on to the child or is added in front of
Expand Down
48 changes: 30 additions & 18 deletions lib/plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,9 @@ Hoek.inherits(internals.Plugin, Kilt);

internals.Plugin.prototype._single = function () {

if (this.connections.length === 1) {
if (this.connections &&
this.connections.length === 1) {

this.info = this.connections[0].info;
this.inject = internals.inject;
this.listener = this.connections[0].listener;
Expand Down Expand Up @@ -123,6 +125,8 @@ internals.Plugin.prototype._select = function (labels, plugin) {
if (labels &&
labels.length) { // Captures both empty arrays and empty strings

Hoek.assert(this.connections, 'Cannot select inside a connectionless plugin');

connections = [];
for (var i = 0, il = this.connections.length; i < il; ++i) {
var connection = this.connections[i];
Expand Down Expand Up @@ -263,30 +267,33 @@ internals.Plugin.prototype.register = function (plugins /*, [options], callback
}

var connections = [];
var originalCount = selection.connections.length;
for (var j = 0, jl = originalCount; j < jl; ++j) {
var connection = selection.connections[j];
if (connection.registrations[item.name]) {
if (item.options.once) {
continue;
if (selection.connections) {
for (var j = 0, jl = selection.connections.length; j < jl; ++j) {
var connection = selection.connections[j];
if (connection.registrations[item.name]) {
if (item.options.once) {
continue;
}

Hoek.assert(item.multiple, 'Plugin', item.name, 'already registered in:', connection.info.uri);
}
else {
connection.registrations[item.name] = { version: item.version };
}

Hoek.assert(item.multiple, 'Plugin', item.name, 'already registered in:', connection.info.uri);
}
else {
connection.registrations[item.name] = { version: item.version };
connections.push(connection);
}

connections.push(connection);
if (item.options.once &&
item.connections &&
!connections.length) {

return next(); // All the connections already registered
}
}

selection.connections = (item.connections ? connections : null);
if (item.options.once &&
!selection.connections.length &&
originalCount) {

return next(); // All the connections already registered
}
selection._single();

if (item.dependencies) {
selection.dependency(item.dependencies);
Expand Down Expand Up @@ -521,6 +528,7 @@ internals.Plugin.prototype.route = function (options) {

Hoek.assert(arguments.length === 1, 'Method requires a single object argument or a single array of objects');
Hoek.assert(typeof options === 'object', 'Invalid route options');
Hoek.assert(this.connections, 'Cannot add route from a connectionless plugin');
Hoek.assert(this.connections.length, 'Cannot add a route without any connections');

this._apply('route', Connection.prototype._route, [options, this.realm]);
Expand All @@ -535,6 +543,8 @@ internals.Plugin.prototype.state = function (name, options) {

internals.Plugin.prototype.table = function (host) {

Hoek.assert(this.connections, 'Cannot request routing table from a connectionless plugin');

var table = [];
for (var i = 0, il = this.connections.length; i < il; ++i) {
var connection = this.connections[i];
Expand All @@ -547,6 +557,7 @@ internals.Plugin.prototype.table = function (host) {

internals.Plugin.prototype._apply = function (type, func, args) {

Hoek.assert(this.connections, 'Cannot add ' + type + ' from a connectionless plugin');
Hoek.assert(this.connections.length, 'Cannot add ' + type + ' without a connection');

for (var i = 0, il = this.connections.length; i < il; ++i) {
Expand All @@ -557,6 +568,7 @@ internals.Plugin.prototype._apply = function (type, func, args) {

internals.Plugin.prototype._applyChild = function (type, child, func, args) {

Hoek.assert(this.connections, 'Cannot add ' + type + ' from a connectionless plugin');
Hoek.assert(this.connections.length, 'Cannot add ' + type + ' without a connection');

for (var i = 0, il = this.connections.length; i < il; ++i) {
Expand Down
22 changes: 16 additions & 6 deletions lib/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -184,12 +184,22 @@ internals.Server.prototype.initialize = function (callback) {

for (var i = 0, il = this._dependencies.length; i < il; ++i) {
var dependency = this._dependencies[i];
for (var s = 0, sl = dependency.connections.length; s < sl; ++s) {
var connection = dependency.connections[s];
for (var d = 0, dl = dependency.deps.length; d < dl; ++d) {
var dep = dependency.deps[d];
if (!connection.registrations[dep]) {
return errorCallback(new Error('Plugin ' + dependency.plugin + ' missing dependency ' + dep + ' in connection: ' + connection.info.uri));
if (dependency.connections) {
for (var s = 0, sl = dependency.connections.length; s < sl; ++s) {
var connection = dependency.connections[s];
for (var d = 0, dl = dependency.deps.length; d < dl; ++d) {
var dep = dependency.deps[d];
if (!connection.registrations[dep]) {
return errorCallback(new Error('Plugin ' + dependency.plugin + ' missing dependency ' + dep + ' in connection: ' + connection.info.uri));
}
}
}
}
else {
for (d = 0, dl = dependency.deps.length; d < dl; ++d) {
dep = dependency.deps[d];
if (!this._registrations[dep]) {
return errorCallback(new Error('Plugin ' + dependency.plugin + ' missing dependency ' + dep));
}
}
}
Expand Down
Loading

0 comments on commit 5c6cef2

Please sign in to comment.