[IMPROVE] Stop sort callbacks on run (#11330)

pull/11358/head^2
Guilherme Gazzo 8 years ago committed by GitHub
parent ae150fb61f
commit d08d48cd0d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 107
      packages/rocketchat-lib/lib/callbacks.js
  2. 26
      packages/rocketchat-lib/lib/promises.js

@ -26,6 +26,7 @@ RocketChat.callbacks.priority = {
LOW: 1000
};
const getHooks = hookName => RocketChat.callbacks[hookName] || [];
/*
* Add a callback function to a hook
@ -33,24 +34,26 @@ RocketChat.callbacks.priority = {
* @param {Function} callback - The callback function
*/
RocketChat.callbacks.add = function(hook, callback, priority, id) {
if (priority == null) {
priority = RocketChat.callbacks.priority.MEDIUM;
}
RocketChat.callbacks.add = function(hook, callback, priority, id = Random.id()) {
if (!_.isNumber(priority)) {
priority = RocketChat.callbacks.priority.MEDIUM;
}
callback.priority = priority;
callback.id = id || Random.id();
RocketChat.callbacks[hook] = RocketChat.callbacks[hook] || [];
callback.id = id;
RocketChat.callbacks[hook] = getHooks(hook);
if (RocketChat.callbacks.showTime === true) {
const err = new Error;
callback.stack = err.stack;
}
if (RocketChat.callbacks[hook].find((cb) => cb.id === callback.id)) {
return;
}
RocketChat.callbacks[hook].push(callback);
RocketChat.callbacks[hook] = _.sortBy(RocketChat.callbacks[hook], function(callback) {
return callback.priority || RocketChat.callbacks.priority.MEDIUM;
});
};
@ -60,8 +63,8 @@ RocketChat.callbacks.add = function(hook, callback, priority, id) {
* @param {string} id - The callback's id
*/
RocketChat.callbacks.remove = function(hookName, id) {
RocketChat.callbacks[hookName] = _.reject(RocketChat.callbacks[hookName], (callback) => callback.id === id);
RocketChat.callbacks.remove = function(hook, id) {
RocketChat.callbacks[hook] = getHooks(hook).filter(callback => callback.id !== id);
};
@ -75,59 +78,56 @@ RocketChat.callbacks.remove = function(hookName, id) {
RocketChat.callbacks.run = function(hook, item, constant) {
const callbacks = RocketChat.callbacks[hook];
if (callbacks && callbacks.length) {
if (!callbacks || !callbacks.length) {
return item;
}
let rocketchatHooksEnd;
if (Meteor.isServer) {
rocketchatHooksEnd = RocketChat.metrics.rocketchatHooks.startTimer({hook, callbacks_length: callbacks.length});
}
let rocketchatHooksEnd;
let totalTime = 0;
const result = callbacks.reduce(function(result, callback) {
let rocketchatCallbacksEnd;
if (Meteor.isServer) {
rocketchatHooksEnd = RocketChat.metrics.rocketchatHooks.startTimer({hook, callbacks_length: callbacks.length});
rocketchatCallbacksEnd = RocketChat.metrics.rocketchatCallbacks.startTimer({hook, callback: callback.id});
}
let totalTime = 0;
const result = _.sortBy(callbacks, function(callback) {
return callback.priority || RocketChat.callbacks.priority.MEDIUM;
}).reduce(function(result, callback) {
let rocketchatCallbacksEnd;
if (Meteor.isServer) {
rocketchatCallbacksEnd = RocketChat.metrics.rocketchatCallbacks.startTimer({hook, callback: callback.id});
}
let time = 0;
if (RocketChat.callbacks.showTime === true || RocketChat.callbacks.showTotalTime === true) {
time = Date.now();
}
const callbackResult = callback(result, constant);
if (RocketChat.callbacks.showTime === true || RocketChat.callbacks.showTotalTime === true) {
const currentTime = Date.now() - time;
totalTime += currentTime;
if (RocketChat.callbacks.showTime === true) {
if (Meteor.isServer) {
rocketchatCallbacksEnd();
RocketChat.statsTracker.timing('callbacks.time', currentTime, [`hook:${ hook }`, `callback:${ callback.id }`]);
} else {
let stack = callback.stack && typeof callback.stack.split === 'function' && callback.stack.split('\n');
stack = stack && stack[2] && (stack[2].match(/\(.+\)/)||[])[0];
console.log(String(currentTime), hook, callback.id, stack);
}
const time = RocketChat.callbacks.showTime === true || RocketChat.callbacks.showTotalTime === true ? Date.now() : 0;
const callbackResult = callback(result, constant);
if (RocketChat.callbacks.showTime === true || RocketChat.callbacks.showTotalTime === true) {
const currentTime = Date.now() - time;
totalTime += currentTime;
if (RocketChat.callbacks.showTime === true) {
if (Meteor.isServer) {
rocketchatCallbacksEnd();
RocketChat.statsTracker.timing('callbacks.time', currentTime, [`hook:${ hook }`, `callback:${ callback.id }`]);
} else {
let stack = callback.stack && typeof callback.stack.split === 'function' && callback.stack.split('\n');
stack = stack && stack[2] && (stack[2].match(/\(.+\)/)||[])[0];
console.log(String(currentTime), hook, callback.id, stack);
}
}
return (typeof callbackResult === 'undefined') ? result : callbackResult;
}, item);
}
return (typeof callbackResult === 'undefined') ? result : callbackResult;
}, item);
if (Meteor.isServer) {
rocketchatHooksEnd();
}
if (RocketChat.callbacks.showTotalTime === true) {
if (Meteor.isServer) {
rocketchatHooksEnd();
RocketChat.statsTracker.timing('callbacks.totalTime', totalTime, [`hook:${ hook }`]);
} else {
console.log(`${ hook }:`, totalTime);
}
}
if (RocketChat.callbacks.showTotalTime === true) {
if (Meteor.isServer) {
RocketChat.statsTracker.timing('callbacks.totalTime', totalTime, [`hook:${ hook }`]);
} else {
console.log(`${ hook }:`, totalTime);
}
}
return result;
return result;
} else {
return item;
}
};
@ -142,9 +142,8 @@ RocketChat.callbacks.runAsync = function(hook, item, constant) {
const callbacks = RocketChat.callbacks[hook];
if (Meteor.isServer && callbacks && callbacks.length) {
Meteor.defer(function() {
_.sortBy(callbacks, (callback) => callback.priority || RocketChat.callbacks.priority.MEDIUM).forEach((callback) => callback(item, constant));
callbacks.forEach(callback => callback(item, constant));
});
} else {
return item;
}
return item;
};

@ -18,6 +18,7 @@ RocketChat.promises.priority = {
LOW: 1000
};
const getHook = hookName => RocketChat.promises[hookName] || [];
/*
* Add a callback function to a hook
@ -26,14 +27,14 @@ RocketChat.promises.priority = {
*/
RocketChat.promises.add = function(hook, callback, p = RocketChat.promises.priority.MEDIUM, id) {
const priority = !_.isNumber(p) ? RocketChat.promises.priority.MEDIUM : p;
callback.priority = priority;
callback.priority = _.isNumber(p) ? p : RocketChat.promises.priority.MEDIUM;
callback.id = id || Random.id();
RocketChat.promises[hook] = RocketChat.promises[hook] || [];
RocketChat.promises[hook] = getHook(hook);
if (RocketChat.promises[hook].find(cb => cb.id === callback.id)) {
return;
}
RocketChat.promises[hook].push(callback);
RocketChat.promises[hook] = _.sortBy(RocketChat.promises[hook], callback => callback.priority || RocketChat.promises.priority.MEDIUM);
};
@ -43,8 +44,8 @@ RocketChat.promises.add = function(hook, callback, p = RocketChat.promises.prior
* @param {string} id - The callback's id
*/
RocketChat.promises.remove = function(hookName, id) {
RocketChat.promises[hookName] = _.reject(RocketChat.promises[hookName], (callback) => callback.id === id);
RocketChat.promises.remove = function(hook, id) {
RocketChat.promises[hook] = getHook(hook).filter(callback => callback.id !== id);
};
@ -57,16 +58,11 @@ RocketChat.promises.remove = function(hookName, id) {
*/
RocketChat.promises.run = function(hook, item, constant) {
let callbacks = RocketChat.promises[hook];
const callbacks = RocketChat.promises[hook];
if (callbacks == null || callbacks.length === 0) {
return Promise.resolve(item);
}
callbacks = _.sortBy(callbacks, (callback) => callback.priority || RocketChat.promises.priority.MEDIUM);
return callbacks.reduce(function(previousPromise, callback) {
return new Promise(function(resolve, reject) {
return previousPromise.then((result) => callback(result, constant).then(resolve, reject));
});
}, Promise.resolve(item));
return callbacks.reduce((previousPromise, callback) => previousPromise.then(result => callback(result, constant)), Promise.resolve(item));
};
@ -82,9 +78,5 @@ RocketChat.promises.runAsync = function(hook, item, constant) {
if (!Meteor.isServer || callbacks == null || callbacks.length === 0) {
return item;
}
Meteor.defer(() => {
_.sortBy(callbacks, (callback) => callback.priority || RocketChat.promises.priority.MEDIUM).forEach(function(callback) {
callback(item, constant);
});
});
Meteor.defer(() => callbacks.forEach(callback => callback(item, constant)));
};

Loading…
Cancel
Save