Move/create rocketchat callbacks (#13034)

* Move rocketchat settings to specific package

* WIP: Move models from rocketchat-lib to a specific package (server)

* Move function from rocketchat:lib to rocketchat:utils to use it in rocketchat:models

* Move client models from rocketchat:lib to rocketchat:models

* Fix lint

* Move rocketchat.info from lib to utils

* Remove directly dependency between lib and migrations

* Move statistics Model to rocketchat:models

* Create rocketchat:metrics to be able to depacking rocketchat callbacks

* Move  callbacks to specific package

* Remove unused dependency

* Merge branch 'develop' into globals/move-rocketchat-callbacks
pull/13119/head
Marcos Spessatto Defendi 6 years ago committed by Rodrigo Nascimento
parent 39bb16182f
commit ff39241b85
  1. 1
      .meteor/packages
  2. 1
      .meteor/versions
  3. 5
      packages/rocketchat-callbacks/client/index.js
  4. 152
      packages/rocketchat-callbacks/lib/callbacks.js
  5. 15
      packages/rocketchat-callbacks/package.js
  6. 5
      packages/rocketchat-callbacks/server/index.js
  7. 147
      packages/rocketchat-lib/lib/callbacks.js
  8. 1
      packages/rocketchat-lib/package.js

@ -205,3 +205,4 @@ rocketchat:utils
rocketchat:settings
rocketchat:models
rocketchat:metrics
rocketchat:callbacks

@ -141,6 +141,7 @@ rocketchat:autotranslate@0.0.1
rocketchat:bigbluebutton@0.0.1
rocketchat:blockstack@0.0.1
rocketchat:bot-helpers@0.0.1
rocketchat:callbacks@0.0.1
rocketchat:cas@1.0.0
rocketchat:channel-settings@0.0.1
rocketchat:channel-settings-mail-messages@0.0.1

@ -0,0 +1,5 @@
import { callbacks } from '../lib/callbacks';
export {
callbacks,
};

@ -0,0 +1,152 @@
import { Meteor } from 'meteor/meteor';
import { Random } from 'meteor/random';
import { metrics, StatsTracker } from 'meteor/rocketchat:metrics';
import _ from 'underscore';
/*
* Callback hooks provide an easy way to add extra steps to common operations.
* @namespace RocketChat.callbacks
*/
export const callbacks = {};
if (Meteor.isServer) {
callbacks.showTime = true;
callbacks.showTotalTime = true;
} else {
callbacks.showTime = false;
callbacks.showTotalTime = false;
}
/*
* Callback priorities
*/
callbacks.priority = {
HIGH: -1000,
MEDIUM: 0,
LOW: 1000,
};
const getHooks = (hookName) => callbacks[hookName] || [];
/*
* Add a callback function to a hook
* @param {String} hook - The name of the hook
* @param {Function} callback - The callback function
*/
callbacks.add = function(hook, callback, priority, id = Random.id()) {
if (!_.isNumber(priority)) {
priority = callbacks.priority.MEDIUM;
}
callback.priority = priority;
callback.id = id;
callbacks[hook] = getHooks(hook);
if (callbacks.showTime === true) {
const err = new Error;
callback.stack = err.stack;
}
if (callbacks[hook].find((cb) => cb.id === callback.id)) {
return;
}
callbacks[hook].push(callback);
callbacks[hook] = _.sortBy(callbacks[hook], function(callback) {
return callback.priority || callbacks.priority.MEDIUM;
});
};
/*
* Remove a callback from a hook
* @param {string} hook - The name of the hook
* @param {string} id - The callback's id
*/
callbacks.remove = function(hook, id) {
callbacks[hook] = getHooks(hook).filter((callback) => callback.id !== id);
};
/*
* Successively run all of a hook's callbacks on an item
* @param {String} hook - The name of the hook
* @param {Object} item - The post, comment, modifier, etc. on which to run the callbacks
* @param {Object} [constant] - An optional constant that will be passed along to each callback
* @returns {Object} Returns the item after it's been through all the callbacks for this hook
*/
callbacks.run = function(hook, item, constant) {
const callbackItems = callbacks[hook];
if (!callbackItems || !callbackItems.length) {
return item;
}
let rocketchatHooksEnd;
if (Meteor.isServer) {
rocketchatHooksEnd = metrics.rocketchatHooks.startTimer({ hook, callbacks_length: callbacks.length });
}
let totalTime = 0;
const result = callbackItems.reduce(function(result, callback) {
let rocketchatCallbacksEnd;
if (Meteor.isServer) {
rocketchatCallbacksEnd = metrics.rocketchatCallbacks.startTimer({ hook, callback: callback.id });
}
const time = callbacks.showTime === true || callbacks.showTotalTime === true ? Date.now() : 0;
const callbackResult = callback(result, constant);
if (callbacks.showTime === true || callbacks.showTotalTime === true) {
const currentTime = Date.now() - time;
totalTime += currentTime;
if (callbacks.showTime === true) {
if (Meteor.isServer) {
rocketchatCallbacksEnd();
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);
if (Meteor.isServer) {
rocketchatHooksEnd();
}
if (callbacks.showTotalTime === true) {
if (Meteor.isServer) {
StatsTracker.timing('callbacks.totalTime', totalTime, [`hook:${ hook }`]);
} else {
console.log(`${ hook }:`, totalTime);
}
}
return result;
};
/*
* Successively run all of a hook's callbacks on an item, in async mode (only works on server)
* @param {String} hook - The name of the hook
* @param {Object} item - The post, comment, modifier, etc. on which to run the callbacks
* @param {Object} [constant] - An optional constant that will be passed along to each callback
*/
callbacks.runAsync = function(hook, item, constant) {
const callbackItems = callbacks[hook];
if (Meteor.isServer && callbackItems && callbackItems.length) {
Meteor.defer(function() {
callbackItems.forEach((callback) => callback(item, constant));
});
}
return item;
};

@ -0,0 +1,15 @@
Package.describe({
name: 'rocketchat:callbacks',
summary: 'Rocketchat Callbacks',
version: '0.0.1',
git: '',
});
Package.onUse(function(api) {
api.use([
'ecmascript',
'rocketchat:metrics',
]);
api.mainModule('client/index.js', 'client');
api.mainModule('server/index.js', 'server');
});

@ -0,0 +1,5 @@
import { callbacks } from '../lib/callbacks';
export {
callbacks,
};

@ -1,151 +1,8 @@
import { Meteor } from 'meteor/meteor';
import { Random } from 'meteor/random';
import _ from 'underscore';
import { callbacks } from 'meteor/rocketchat:callbacks';
/*
* Callback hooks provide an easy way to add extra steps to common operations.
* @namespace RocketChat.callbacks
*/
RocketChat.callbacks = {};
if (Meteor.isServer) {
RocketChat.callbacks.showTime = true;
RocketChat.callbacks.showTotalTime = true;
} else {
RocketChat.callbacks.showTime = false;
RocketChat.callbacks.showTotalTime = false;
}
/*
* Callback priorities
*/
RocketChat.callbacks.priority = {
HIGH: -1000,
MEDIUM: 0,
LOW: 1000,
};
const getHooks = (hookName) => RocketChat.callbacks[hookName] || [];
/*
* Add a callback function to a hook
* @param {String} hook - The name of the hook
* @param {Function} callback - The callback function
*/
RocketChat.callbacks.add = function(hook, callback, priority, id = Random.id()) {
if (!_.isNumber(priority)) {
priority = RocketChat.callbacks.priority.MEDIUM;
}
callback.priority = priority;
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;
});
};
/*
* Remove a callback from a hook
* @param {string} hook - The name of the hook
* @param {string} id - The callback's id
*/
RocketChat.callbacks.remove = function(hook, id) {
RocketChat.callbacks[hook] = getHooks(hook).filter((callback) => callback.id !== id);
};
/*
* Successively run all of a hook's callbacks on an item
* @param {String} hook - The name of the hook
* @param {Object} item - The post, comment, modifier, etc. on which to run the callbacks
* @param {Object} [constant] - An optional constant that will be passed along to each callback
* @returns {Object} Returns the item after it's been through all the callbacks for this hook
*/
RocketChat.callbacks.run = function(hook, item, constant) {
const callbacks = RocketChat.callbacks[hook];
if (!callbacks || !callbacks.length) {
return item;
}
let rocketchatHooksEnd;
if (Meteor.isServer) {
rocketchatHooksEnd = RocketChat.metrics.rocketchatHooks.startTimer({ hook, callbacks_length: callbacks.length });
}
let totalTime = 0;
const result = callbacks.reduce(function(result, callback) {
let rocketchatCallbacksEnd;
if (Meteor.isServer) {
rocketchatCallbacksEnd = RocketChat.metrics.rocketchatCallbacks.startTimer({ hook, callback: callback.id });
}
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);
if (Meteor.isServer) {
rocketchatHooksEnd();
}
if (RocketChat.callbacks.showTotalTime === true) {
if (Meteor.isServer) {
RocketChat.statsTracker.timing('callbacks.totalTime', totalTime, [`hook:${ hook }`]);
} else {
console.log(`${ hook }:`, totalTime);
}
}
return result;
};
/*
* Successively run all of a hook's callbacks on an item, in async mode (only works on server)
* @param {String} hook - The name of the hook
* @param {Object} item - The post, comment, modifier, etc. on which to run the callbacks
* @param {Object} [constant] - An optional constant that will be passed along to each callback
*/
RocketChat.callbacks.runAsync = function(hook, item, constant) {
const callbacks = RocketChat.callbacks[hook];
if (Meteor.isServer && callbacks && callbacks.length) {
Meteor.defer(function() {
callbacks.forEach((callback) => callback(item, constant));
});
}
return item;
};
RocketChat.callbacks = callbacks;

@ -28,6 +28,7 @@ Package.onUse(function(api) {
api.use('rocketchat:models');
api.use('rocketchat:migrations');
api.use('rocketchat:metrics');
api.use('rocketchat:callbacks');
api.use('rocketchat:accounts');
api.use('modules');
api.use('rocketchat:i18n');

Loading…
Cancel
Save