Skip to content
Snippets Groups Projects
Unverified Commit 9fc09c81 authored by Rodrigo Nascimento's avatar Rodrigo Nascimento
Browse files

Fix client sync on reconnect

parent 300041bc
No related branches found
No related tags found
No related merge requests found
...@@ -8,7 +8,8 @@ Meteor.methods({ ...@@ -8,7 +8,8 @@ Meteor.methods({
return { return {
update: records.filter((record) => { update: records.filter((record) => {
return record._updatedAt > updatedAt; return record._updatedAt > updatedAt;
}) }),
remove: RocketChat.models.Permissions.trashFindDeletedAfter(updatedAt, {}, {fields: {_id: 1, _deletedAt: 1}}).fetch()
}; };
} }
......
...@@ -4,12 +4,26 @@ class CachedCollectionManager { ...@@ -4,12 +4,26 @@ class CachedCollectionManager {
constructor() { constructor() {
this.items = []; this.items = [];
this._syncEnabled = false; this._syncEnabled = false;
this.reconnectCb = [];
const _unstoreLoginToken = Accounts._unstoreLoginToken; const _unstoreLoginToken = Accounts._unstoreLoginToken;
Accounts._unstoreLoginToken = (...args) => { Accounts._unstoreLoginToken = (...args) => {
_unstoreLoginToken.apply(Accounts, args); _unstoreLoginToken.apply(Accounts, args);
this.clearAllCache(); this.clearAllCache();
}; };
let connectionWasOnline = true;
Tracker.autorun(() => {
const connected = Meteor.connection.status().connected;
if (connected === true && connectionWasOnline === false) {
for (const cb of this.reconnectCb) {
cb();
}
}
connectionWasOnline = connected;
});
} }
register(cachedCollection) { register(cachedCollection) {
...@@ -36,6 +50,10 @@ class CachedCollectionManager { ...@@ -36,6 +50,10 @@ class CachedCollectionManager {
get syncEnabled() { get syncEnabled() {
return this._syncEnabled; return this._syncEnabled;
} }
onReconnect(cb) {
this.reconnectCb.push(cb);
}
} }
RocketChat.CachedCollectionManager = new CachedCollectionManager; RocketChat.CachedCollectionManager = new CachedCollectionManager;
...@@ -49,7 +67,7 @@ class CachedCollection { ...@@ -49,7 +67,7 @@ class CachedCollection {
syncMethodName, syncMethodName,
eventName, eventName,
eventType = 'onUser', eventType = 'onUser',
useSync = false, useSync = true,
useCache = false, useCache = false,
debug = true, debug = true,
version = 1, version = 1,
...@@ -70,6 +88,10 @@ class CachedCollection { ...@@ -70,6 +88,10 @@ class CachedCollection {
this.updatedAt = new Date(0); this.updatedAt = new Date(0);
this.maxCacheTime = maxCacheTime; this.maxCacheTime = maxCacheTime;
if (this.useCache === false) {
return this.clearCache();
}
RocketChat.CachedCollectionManager.register(this); RocketChat.CachedCollectionManager.register(this);
} }
...@@ -166,28 +188,48 @@ class CachedCollection { ...@@ -166,28 +188,48 @@ class CachedCollection {
this.log(`syncing from ${this.updatedAt}`); this.log(`syncing from ${this.updatedAt}`);
Meteor.call(this.syncMethodName, this.updatedAt, (error, data) => { Meteor.call(this.syncMethodName, this.updatedAt, (error, data) => {
let changes = [];
if (data.update && data.update.length > 0) { if (data.update && data.update.length > 0) {
this.log(`${data.update.length} records updated in sync`); this.log(`${data.update.length} records updated in sync`);
changes.push(...data.update);
for (const record of data.update) {
delete record.$loki;
this.collection.upsert({ _id: record._id }, _.omit(record, '_id'));
if (record._updatedAt && record._updatedAt > this.updatedAt) {
this.updatedAt = record._updatedAt;
}
}
} }
if (data.remove && data.remove.length > 0) { if (data.remove && data.remove.length > 0) {
this.log(`${data.remove.length} records removed in sync`); this.log(`${data.remove.length} records removed in sync`);
changes.push(...data.remove);
}
changes = changes.sort((a, b) => {
const valueA = a._updatedAt || a._deletedAt;
const valueB = b._updatedAt || b._deletedAt;
for (const record of data.remove) { if (valueA < valueB) {
return -1;
}
if (valueA > valueB) {
return 1;
}
return 0;
});
for (const record of changes) {
delete record.$loki;
if (record._deletedAt) {
this.collection.remove({ _id: record._id }); this.collection.remove({ _id: record._id });
if (record._deletedAt && record._deletedAt > this.updatedAt) { if (record._deletedAt && record._deletedAt > this.updatedAt) {
this.updatedAt = record._deletedAt; this.updatedAt = record._deletedAt;
} }
} else {
this.collection.upsert({ _id: record._id }, _.omit(record, '_id'));
if (record._updatedAt && record._updatedAt > this.updatedAt) {
this.updatedAt = record._updatedAt;
}
} }
} }
...@@ -198,6 +240,10 @@ class CachedCollection { ...@@ -198,6 +240,10 @@ class CachedCollection {
} }
saveCache(data) { saveCache(data) {
if (this.useCache === false) {
return;
}
this.log('saving cache'); this.log('saving cache');
if (!data) { if (!data) {
data = this.collection.find().fetch(); data = this.collection.find().fetch();
...@@ -256,15 +302,8 @@ class CachedCollection { ...@@ -256,15 +302,8 @@ class CachedCollection {
} }
if (this.useSync === true) { if (this.useSync === true) {
let connectionWasOnline = true; RocketChat.CachedCollectionManager.onReconnect(() => {
Tracker.autorun(() => { this.trySync();
const connected = Meteor.connection.status().connected;
if (connected === true && connectionWasOnline === false) {
this.trySync();
}
connectionWasOnline = connected;
}); });
} }
......
...@@ -31,6 +31,7 @@ Meteor.methods ...@@ -31,6 +31,7 @@ Meteor.methods
return { return {
update: records.filter (record) -> update: records.filter (record) ->
return record._updatedAt > updatedAt return record._updatedAt > updatedAt
remove: RocketChat.models.Settings.trashFindDeletedAfter(updatedAt, {hidden: { $ne: true }}, {fields: {_id: 1, _deletedAt: 1}}).fetch()
} }
return records return records
......
...@@ -38,8 +38,9 @@ Meteor.methods({ ...@@ -38,8 +38,9 @@ Meteor.methods({
return { return {
update: data update: data
.filter(record => { return record._room && record._room._updatedAt > updatedAt; }) .filter(record => { return record._room && record._room._updatedAt > updatedAt; })
.map(roomMap) .map(roomMap),
}; remove: RocketChat.models.Subscriptions.trashFindDeletedAfter(updatedAt, {'u._id': Meteor.userId()}, {fields: {_id: 1, _deletedAt: 1}}).fetch()
};
} }
return data.map(roomMap); return data.map(roomMap);
......
...@@ -35,6 +35,7 @@ Meteor.methods ...@@ -35,6 +35,7 @@ Meteor.methods
return { return {
update: records.filter (record) -> update: records.filter (record) ->
return record._updatedAt > updatedAt return record._updatedAt > updatedAt
remove: RocketChat.models.Subscriptions.trashFindDeletedAfter(updatedAt, {'u._id': Meteor.userId()}, {fields: {_id: 1, _deletedAt: 1}}).fetch()
} }
return records return records
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment