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 merge requests found
......@@ -8,7 +8,8 @@ Meteor.methods({
return {
update: records.filter((record) => {
return record._updatedAt > updatedAt;
})
}),
remove: RocketChat.models.Permissions.trashFindDeletedAfter(updatedAt, {}, {fields: {_id: 1, _deletedAt: 1}}).fetch()
};
}
......
......@@ -4,12 +4,26 @@ class CachedCollectionManager {
constructor() {
this.items = [];
this._syncEnabled = false;
this.reconnectCb = [];
const _unstoreLoginToken = Accounts._unstoreLoginToken;
Accounts._unstoreLoginToken = (...args) => {
_unstoreLoginToken.apply(Accounts, args);
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) {
......@@ -36,6 +50,10 @@ class CachedCollectionManager {
get syncEnabled() {
return this._syncEnabled;
}
onReconnect(cb) {
this.reconnectCb.push(cb);
}
}
RocketChat.CachedCollectionManager = new CachedCollectionManager;
......@@ -49,7 +67,7 @@ class CachedCollection {
syncMethodName,
eventName,
eventType = 'onUser',
useSync = false,
useSync = true,
useCache = false,
debug = true,
version = 1,
......@@ -70,6 +88,10 @@ class CachedCollection {
this.updatedAt = new Date(0);
this.maxCacheTime = maxCacheTime;
if (this.useCache === false) {
return this.clearCache();
}
RocketChat.CachedCollectionManager.register(this);
}
......@@ -166,28 +188,48 @@ class CachedCollection {
this.log(`syncing from ${this.updatedAt}`);
Meteor.call(this.syncMethodName, this.updatedAt, (error, data) => {
let changes = [];
if (data.update && data.update.length > 0) {
this.log(`${data.update.length} records updated in sync`);
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;
}
}
changes.push(...data.update);
}
if (data.remove && data.remove.length > 0) {
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 });
if (record._deletedAt && record._deletedAt > this.updatedAt) {
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 {
}
saveCache(data) {
if (this.useCache === false) {
return;
}
this.log('saving cache');
if (!data) {
data = this.collection.find().fetch();
......@@ -256,15 +302,8 @@ class CachedCollection {
}
if (this.useSync === true) {
let connectionWasOnline = true;
Tracker.autorun(() => {
const connected = Meteor.connection.status().connected;
if (connected === true && connectionWasOnline === false) {
this.trySync();
}
connectionWasOnline = connected;
RocketChat.CachedCollectionManager.onReconnect(() => {
this.trySync();
});
}
......
......@@ -31,6 +31,7 @@ Meteor.methods
return {
update: records.filter (record) ->
return record._updatedAt > updatedAt
remove: RocketChat.models.Settings.trashFindDeletedAfter(updatedAt, {hidden: { $ne: true }}, {fields: {_id: 1, _deletedAt: 1}}).fetch()
}
return records
......
......@@ -38,8 +38,9 @@ Meteor.methods({
return {
update: data
.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);
......
......@@ -35,6 +35,7 @@ Meteor.methods
return {
update: records.filter (record) ->
return record._updatedAt > updatedAt
remove: RocketChat.models.Subscriptions.trashFindDeletedAfter(updatedAt, {'u._id': Meteor.userId()}, {fields: {_id: 1, _deletedAt: 1}}).fetch()
}
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