Skip to content

Commit

Permalink
[IMPROVE] Replace userData subscriptions by REST (RocketChat#15916)
Browse files Browse the repository at this point in the history
  • Loading branch information
MarcosSpessatto authored and sampaiodiego committed Dec 18, 2019
1 parent a50a170 commit c2f6f82
Show file tree
Hide file tree
Showing 10 changed files with 67 additions and 41 deletions.
2 changes: 1 addition & 1 deletion .meteor/versions
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ rocketchat:livechat@0.0.1
rocketchat:mongo-config@0.0.1
rocketchat:oauth2-server@2.1.0
rocketchat:push@3.3.1
rocketchat:streamer@1.0.2
rocketchat:streamer@1.1.0
rocketchat:tap-i18n@1.9.1
rocketchat:version@1.0.0
routepolicy@1.1.0
Expand Down
1 change: 1 addition & 0 deletions app/lib/server/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import './startup/settings';
import './startup/settingsOnLoadCdnPrefix';
import './startup/settingsOnLoadDirectReply';
import './startup/settingsOnLoadSMTP';
import './startup/userDataStream';
import '../lib/MessageTypes';
import '../startup';
import '../startup/defaultRoomTypes';
Expand Down
16 changes: 16 additions & 0 deletions app/lib/server/startup/userDataStream.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Users } from '../../../models/server';
import { Notifications } from '../../../notifications/server';

Users.on('change', ({ clientAction, id, data, diff }) => {
switch (clientAction) {
case 'updated':
Notifications.notifyUser(id, 'userData', { diff, type: clientAction });
break;
case 'inserted':
Notifications.notifyUser(id, 'userData', { data, type: clientAction });
break;
case 'removed':
Notifications.notifyUser(id, 'userData', { id, type: clientAction });
break;
}
});
10 changes: 0 additions & 10 deletions app/models/client/models/Users.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,3 @@ export const Users = {
// overwrite Meteor.users collection so records on it don't get erased whenever the client reconnects to websocket
Meteor.users = new Mongo.Collection(null);
Meteor.user = () => Meteor.users.findOne({ _id: Meteor.userId() });

// logged user data will come to this collection
const OwnUser = new Mongo.Collection('own_user');

// register an observer to logged user's collection and populate "original" Meteor.users with it
OwnUser.find().observe({
added: (record) => Meteor.users.upsert({ _id: record._id }, record),
changed: (record) => Meteor.users.update({ _id: record._id }, record),
removed: (_id) => Meteor.users.remove({ _id }),
});
5 changes: 2 additions & 3 deletions app/ui-master/client/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { CachedCollectionManager } from '../../ui-cached-collection';
import { hasRole } from '../../authorization';
import { tooltip } from '../../ui/client/components/tooltip';
import { callbacks } from '../../callbacks/client';
import { isSyncReady } from '../../../client/lib/userData';

function executeCustomScript(script) {
eval(script);//eslint-disable-line
Expand Down Expand Up @@ -171,11 +172,9 @@ Template.main.helpers({
return iframeEnabled && iframeLogin.reactiveIframeUrl.get();
},
subsReady() {
const routerReady = FlowRouter.subsReady('userData');
const subscriptionsReady = CachedChatSubscription.ready.get();
const settingsReady = settings.cachedCollection.ready.get();

const ready = (routerReady && subscriptionsReady && settingsReady) || !Meteor.userId();
const ready = !Meteor.userId() || (isSyncReady.get() && subscriptionsReady && settingsReady);

CachedCollectionManager.syncEnabled = ready;
mainReady.set(ready);
Expand Down
1 change: 1 addition & 0 deletions app/utils/server/functions/getDefaultUserFields.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,5 @@ export const getDefaultUserFields = () => ({
'services.totp.enabled': 1,
statusLivechat: 1,
banners: 1,
_updatedAt: 1,
});
40 changes: 40 additions & 0 deletions client/lib/userData.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { ReactiveVar } from 'meteor/reactive-var';
import { Meteor } from 'meteor/meteor';

import { APIClient } from '../../app/utils/client';
import { Users } from '../../app/models/client';
import { Notifications } from '../../app/notifications/client';

export const isSyncReady = new ReactiveVar(false);

function updateUser(userData) {
const user = Users.findOne({ _id: userData._id });
if (!user || userData._updatedAt > user._updatedAt) {
return Meteor.users.upsert({ _id: userData._id }, userData);
}
// delete data already on user's collection as those are newer
Object.keys(user).forEach((key) => delete userData[key]);
Meteor.users.update({ _id: user._id }, { $set: userData });
}

const onUserEvents = {
inserted: (_id, data) => Meteor.users.insert(data),
updated: (_id, { diff }) => Meteor.users.upsert({ _id }, { $set: diff }),
removed: (_id) => Meteor.users.remove({ _id }),
};

export const syncUserdata = async (uid) => {
if (!uid) {
return;
}

await Notifications.onUser('userData', ({ type, id, ...data }) => onUserEvents[type](uid, data));

const userData = await APIClient.v1.get('me');
if (userData) {
updateUser(userData);
}
isSyncReady.set(true);

return userData;
};
8 changes: 0 additions & 8 deletions client/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,14 +85,6 @@ const createTemplateForComponent = async (
return name;
};

FlowRouter.subscriptions = function() {
Tracker.autorun(() => {
if (Meteor.userId()) {
this.register('userData', Meteor.subscribe('userData'));
}
});
};

FlowRouter.route('/', {
name: 'index',
action() {
Expand Down
24 changes: 5 additions & 19 deletions client/startup/startup.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,9 @@ import toastr from 'toastr';
import hljs from 'highlight.js';

import { fireGlobalEvent } from '../../app/ui-utils';
import { settings } from '../../app/settings';
import { Users } from '../../app/models';
import { getUserPreference } from '../../app/utils';
import 'highlight.js/styles/github.css';
import { syncUserdata } from '../lib/userData';

hljs.initHighlightingOnLoad();

Expand All @@ -29,27 +28,14 @@ Meteor.startup(function() {
window.lastMessageWindow = {};
window.lastMessageWindowHistory = {};

Tracker.autorun(function(computation) {
if (!Meteor.userId() && !settings.get('Accounts_AllowAnonymousRead')) {
return;
}
Meteor.subscribe('userData');
computation.stop();
});

let status = undefined;
Tracker.autorun(function() {
if (!Meteor.userId()) {
Tracker.autorun(async function() {
const uid = Meteor.userId();
if (!uid) {
return;
}
const user = Users.findOne(Meteor.userId(), {
fields: {
status: 1,
'settings.preferences.idleTimeLimit': 1,
'settings.preferences.enableAutoAway': 1,
},
});

const user = await syncUserdata(uid);
if (!user) {
return;
}
Expand Down
1 change: 1 addition & 0 deletions server/publications/userData.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Users } from '../../app/models';
import { getDefaultUserFields } from '../../app/utils/server/functions/getDefaultUserFields';

Meteor.publish('userData', function() {
console.warn('The publication "userData" is deprecated and will be removed after version v3.0.0');
if (!this.userId) {
return this.ready();
}
Expand Down

0 comments on commit c2f6f82

Please sign in to comment.