Skip to content

Commit

Permalink
[rebase] take #1305 as a workbase
Browse files Browse the repository at this point in the history
  • Loading branch information
scottinet committed May 24, 2019
1 parent 5b46e5f commit 2501ab7
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 112 deletions.
116 changes: 12 additions & 104 deletions lib/api/core/plugins/pluginsManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -206,34 +206,30 @@ class PluginsManager {
* provided data, which is then passed to the next listener, and so on in
* series until the last listener resolves.
*
* @param {string} event
* @param {Array.<string>} events
* @param {*} data
* @return {Promise.<*>}
*/
pipe(event, data) {
debug('trigger "%s" event', event);
pipe(events, data) {
debug('trigger "%s" event', events);

let preparedPipes = [];
const wildcardEvent = getWildcardEvent(event);
const preparedPipes = [cb => cb(null, data)];

if (this.pipes && this.pipes[event] && this.pipes[event].length) {
preparedPipes = this.pipes[event];
}
let i; // NOSONAR
for (i = 0; i < events.length; i++) {
const event = events[i];

if (wildcardEvent && this.pipes && this.pipes[wildcardEvent] &&
this.pipes[wildcardEvent].length
) {
preparedPipes = preparedPipes.concat(this.pipes[wildcardEvent]);
if (this.pipes[event]) {
preparedPipes.push(...this.pipes[event]);
}
}

if (preparedPipes.length === 0) {
if (preparedPipes.length === 1) {
return Bluebird.resolve(data);
}

return new Bluebird((resolve, reject) => {
const callbacks = [cb => cb(null, data)].concat(preparedPipes);

async.waterfall(callbacks, (error, result) => {
async.waterfall(preparedPipes, (error, result) => {
if (error) {
if (error instanceof KuzzleError) {
return reject(error);
Expand Down Expand Up @@ -859,94 +855,6 @@ class PluginsManager {
}
}

/**
* Emit event
*
* @param {EventEmitter} emitter
* @param {string} event
* @param {*} data
* @returns {Promise}
*/
function triggerHooks(emitter, event, data) {
const wildcardEvents = getWildcardEvents(event);

emitter.emit(event, data);

wildcardEvents.forEach(wildcardEvent => emitter.emit(wildcardEvent, data));

return Bluebird.resolve(data);
}

/**
* Chain call all attached functions plugins on the specific event
*
* @param {object} pipes
* @param {string} event
* @param {*} data
* @returns {Promise}
*/
function triggerPipes(pipes, event, data) {
const preparedPipes = [];
const wildcardEvents = getWildcardEvents(event);

if (pipes && pipes[event] && pipes[event].length) {
preparedPipes.push(...pipes[event]);
}

wildcardEvents.forEach(wildcardEvent => {
if (pipes[wildcardEvent] && pipes[wildcardEvent].length) {
preparedPipes.push(...pipes[wildcardEvent]);
}
});

if (preparedPipes.length === 0) {
return Bluebird.resolve(data);
}

return new Bluebird((resolve, reject) => {
async.waterfall([callback => callback(null, data)].concat(preparedPipes), (error, result) => {
if (error) {
if (error instanceof KuzzleError) {
return reject(error);
}

return reject(new PluginImplementationError(error));
}

resolve(result);
});
});
}

/**
* For a specific event, return the correspondings wildcards
* @example
* getWildcardEvents('data:create') // return ['data:*']
* getWildcardEvents('data:beforeCreate') // return ['data:*', 'data:before*']
* @param {String} event
* @returns {Array<String>} wildcard events
*/
const getWildcardEvents = _.memoize(event => {
const delimIndex = event.lastIndexOf(':');

if (delimIndex === -1) {
return [];
}

const scope = event.slice(0, delimIndex);
const name = event.slice(delimIndex + 1);
const wildcardEvents = ['*'];

['before', 'after'].forEach(prefix => {
if (!name.startsWith(prefix)) {
return;
}
wildcardEvents.push(`${prefix}*`);
});

return wildcardEvents.map(e => `${scope}:${e}`);
});

/**
* Test if the provided argument is a constructor or not
*
Expand Down
60 changes: 58 additions & 2 deletions lib/api/kuzzle.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const
path = require('path'),
murmur = require('murmurhash-native').murmurHash128,
stringify = require('json-stable-stringify'),
_ = require('lodash'),
Koncorde = require('koncorde'),
EntryPoints = require('./core/entrypoints'),
FunnelController = require('./controllers/funnelController'),
Expand All @@ -49,6 +50,40 @@ const
InternalEngineBootstrap = require('../services/internalEngine/bootstrap'),
runShutdown = require('../util/shutdown');

/**
* For a specific event, returns the event and all its wildcarded versions
* @example
* getWildcardEvents('data:create') // return ['data:create', 'data:*']
* getWildcardEvents('data:beforeCreate') // return ['data:beforeCreate',
* // 'data:*', 'data:before*']
* @param {String} event
* @returns {Array<String>} wildcard events
*/
const getWildcardEvents = _.memoize(event => {
const
events = [event],
delimIndex = event.lastIndexOf(':');

if (delimIndex === -1) {
return events;
}

const
scope = event.slice(0, delimIndex),
name = event.slice(delimIndex + 1);

['before', 'after'].forEach(prefix => {
if (name.startsWith(prefix)) {
events.push(`${scope}:${prefix}*`);
}
});

events.push(`${scope}:*`);

return events;
});


/**
* @class Kuzzle
* @extends EventEmitter
Expand Down Expand Up @@ -162,6 +197,21 @@ class Kuzzle extends EventEmitter {
});
}

/**
* Emits an event and all its wildcarded versions
*
* @param {string} event
* @param {*} data
*/
emit(event, data) {
const events = getWildcardEvents(event);

let i; // NOSONAR
for (i = 0; i < events.length; i++) {
super.emit(events[i], data);
}
}

/**
* Chains all registered pipes on an event, and then emits it the regular
* way.
Expand All @@ -171,9 +221,15 @@ class Kuzzle extends EventEmitter {
* @return {Promise.<*>}
*/
pipe(event, data) {
return this.pluginsManager.pipe(event, data)
const events = getWildcardEvents(event);

return this.pluginsManager.pipe(events, data)
.then(updated => {
this.emit(event, updated);
let i; // NOSONAR
for (i = 0; i < events.length; i++) {
super.emit(events[i], updated);
}

return updated;
});
}
Expand Down
15 changes: 9 additions & 6 deletions test/api/core/pluginsManager/pipe.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ describe('pluginsManager.pipe', () => {
const PluginsManager = mockrequire.reRequire('../../../../lib/api/core/plugins/pluginsManager');

kuzzle = new KuzzleMock();
kuzzle.emit.restore();
kuzzle.pipe.restore();
pluginsManager = new PluginsManager(kuzzle);
kuzzle.pluginsManager = pluginsManager;
});

it('should trigger hooks with wildcard event', done => {
Expand Down Expand Up @@ -67,7 +70,7 @@ describe('pluginsManager.pipe', () => {

pluginsManager.run()
.then(() => {
pluginsManager.trigger('foo:beforeBar');
kuzzle.emit('foo:beforeBar');
});
});

Expand All @@ -89,7 +92,7 @@ describe('pluginsManager.pipe', () => {

pluginsManager.run()
.then(() => {
pluginsManager.trigger('foo:afterBar');
kuzzle.emit('foo:afterBar');
});
});

Expand All @@ -110,7 +113,7 @@ describe('pluginsManager.pipe', () => {
}];

return pluginsManager.run()
.then(() => pluginsManager.trigger('foo:bar'))
.then(() => kuzzle.pipe('foo:bar'))
.then(() => {
should(pluginsManager.plugins[0].object.myFunc).be.calledOnce();
});
Expand All @@ -133,7 +136,7 @@ describe('pluginsManager.pipe', () => {
}];

return pluginsManager.run()
.then(() => pluginsManager.trigger('foo:beforeBar'))
.then(() => kuzzle.pipe('foo:beforeBar'))
.then(() => {
should(pluginsManager.plugins[0].object.myFunc).be.calledOnce();
});
Expand All @@ -156,7 +159,7 @@ describe('pluginsManager.pipe', () => {
}];

return pluginsManager.run()
.then(() => pluginsManager.trigger('foo:afterBar'))
.then(() => kuzzle.pipe('foo:afterBar'))
.then(() => {
should(pluginsManager.plugins[0].object.myFunc).be.calledOnce();
});
Expand Down Expand Up @@ -184,7 +187,7 @@ describe('pluginsManager.pipe', () => {

pluginsManager.registerPipe(pluginMock, 50, 200, 'foo:bar', 'myFunc');

return should(pluginsManager.pipe('foo:bar')).rejectedWith(
return should(kuzzle.pipe('foo:bar')).rejectedWith(
PluginImplementationError,
{message: /^Plugin foo pipe for event 'foo:bar' threw a non-Kuzzle error: Error: foobar.*/});
});
Expand Down

0 comments on commit 2501ab7

Please sign in to comment.