1
0
mirror of https://github.com/matrix-org/matrix-js-sdk.git synced 2025-08-09 10:22:46 +03:00

Further reorganising of indexeddb sync code

* Make sync communicate with the sync accumulator via the store
 * Consequently get rid of getSyncAccumulator as it's now
   unnecessary.
 * Make the bit that gets the saved sync response async, because
   we'll need it to be when it's coming over postMessage from a
   webworker.
This commit is contained in:
David Baker
2017-03-31 18:18:53 +01:00
parent aebbe4f254
commit c0bd2c8945
5 changed files with 55 additions and 62 deletions

View File

@@ -164,8 +164,6 @@ function MatrixClient(opts) {
this.olmVersion = Crypto.getOlmVersion();
}
this._syncAccumulator = this.store.getSyncAccumulator();
}
utils.inherits(MatrixClient, EventEmitter);
utils.extend(MatrixClient.prototype, MatrixBaseApis.prototype);
@@ -2789,7 +2787,6 @@ MatrixClient.prototype.startClient = function(opts) {
opts = Object.assign({}, opts);
opts.crypto = this._crypto;
opts.syncAccumulator = this._syncAccumulator;
opts.canResetEntireTimeline = (roomId) => {
if (!this._canResetTimelineCallback) {
return false;

View File

@@ -288,17 +288,27 @@ IndexedDBStore.prototype.startup = function() {
});
this._syncTs = Date.now(); // pretend we've written so we don't rewrite
this.setSyncToken(syncData.nextBatch);
this._setSyncData(syncData.nextBatch, syncData.roomsData, accountData);
this.setSyncData({
next_batch: syncData.nextBatch,
rooms: syncData.roomsData,
account_data: {
events: accountData,
},
});
});
};
/**
* Return the accumulator which will have the initial /sync data when startup()
* is called.
* @return {SyncAccumulator}
* @return {Promise} Resolves with a sync response to restore the
* client state to where it was at the last save, or null if there
* is no saved sync data.
*/
IndexedDBStore.prototype.getSyncAccumulator = function() {
return this._syncAccumulator;
IndexedDBStore.prototype.getSavedSync = function() {
const data = this._syncAccumulator.getJSON();
if (!data.nextBatch) return q(null);
// We must deep copy the stored data so that the /sync processing code doesn't
// corrupt the internal state of the sync accumulator (it adds non-clonable keys)
return q(utils.deepCopy(data));
};
/**
@@ -327,14 +337,8 @@ IndexedDBStore.prototype.save = function() {
return q();
};
IndexedDBStore.prototype._setSyncData = function(nextBatch, roomsData, accountData) {
this._syncAccumulator.accumulate({
next_batch: nextBatch,
rooms: roomsData,
account_data: {
events: accountData,
},
});
IndexedDBStore.prototype.setSyncData = function(syncData) {
this._syncAccumulator.accumulate(syncData);
};
IndexedDBStore.prototype._syncToDatabase = function() {

View File

@@ -277,19 +277,16 @@ module.exports.MatrixInMemoryStore.prototype = {
return this.accountData[eventType];
},
/**
* setSyncData does nothing as there is no backing data store.
*/
setSyncData: function(syncData) {},
/**
* Save does nothing as there is no backing data store.
*/
save: function() {},
/**
* Returns nothing as this store does not accumulate /sync data.
* @return {?SyncAccumulator} null
*/
getSyncAccumulator: function() {
return null;
},
/**
* Startup does nothing as this store doesn't require starting up.
* @return {Promise} An immediately resolved promise.

View File

@@ -182,19 +182,16 @@ StubStore.prototype = {
},
/**
* setSyncData does nothing as there is no backing data store.
*/
setSyncData: function(syncData) {},
/**
* Save does nothing as there is no backing data store.
*/
save: function() {},
/**
* Returns nothing as this store does not accumulate /sync data.
* @return {?SyncAccumulator} null
*/
getSyncAccumulator: function() {
return null;
},
/**
* Startup does nothing.
* @return {Promise} An immediately resolved promise.

View File

@@ -60,7 +60,6 @@ function debuglog() {
* @param {MatrixClient} client The matrix client instance to use.
* @param {Object} opts Config options
* @param {module:crypto=} opts.crypto Crypto manager
* @param {SyncAccumulator=} opts.syncAccumulator An accumulator which will be
* kept up-to-date. If one is supplied, the response to getJSON() will be used
* initially.
* @param {Function=} opts.canResetEntireTimeline A function which is called
@@ -542,34 +541,35 @@ SyncApi.prototype._sync = function(syncOptions) {
}
let isCachedResponse = false;
if (self.opts.syncAccumulator && !syncOptions.hasSyncedBefore) {
let data = self.opts.syncAccumulator.getJSON();
let syncPromise;
if (!syncOptions.hasSyncedBefore) {
// Don't do an HTTP hit to /sync. Instead, load up the persisted /sync data,
// if there is data there.
if (data.nextBatch) {
syncPromise = client.store.getSavedSync();
} else {
syncPromise = q(null);
}
syncPromise.then((savedSync) => {
if (savedSync) {
debuglog("sync(): not doing HTTP hit, instead returning stored /sync data");
// We must deep copy the stored data so that the /sync processing code doesn't
// corrupt the internal state of the sync accumulator (it adds non-clonable keys)
data = utils.deepCopy(data);
this._currentSyncRequest = q.resolve({
next_batch: data.nextBatch,
rooms: data.roomsData,
account_data: {
events: data.accountData,
},
});
isCachedResponse = true;
return {
next_batch: savedSync.nextBatch,
rooms: savedSync.roomsData,
account_data: {
events: savedSync.accountData,
},
};
} else {
//debuglog('Starting sync since=' + syncToken);
this._currentSyncRequest = client._http.authedRequest(
undefined, "GET", "/sync", qps, undefined, clientSideTimeoutMs,
);
return this._currentSyncRequest;
}
}
if (!isCachedResponse) {
//debuglog('Starting sync since=' + syncToken);
this._currentSyncRequest = client._http.authedRequest(
undefined, "GET", "/sync", qps, undefined, clientSideTimeoutMs,
);
}
this._currentSyncRequest.done(function(data) {
}).done(function(data) {
//debuglog('Completed sync, next_batch=' + data.next_batch);
// set the sync token NOW *before* processing the events. We do this so
@@ -585,11 +585,9 @@ SyncApi.prototype._sync = function(syncOptions) {
console.error("Caught /sync error", e.stack || e);
}
// If there's an accumulator then the first HTTP response is actually the
// accumulated data. We don't want to accumulate the same thing twice, so
// only accumulate if this isn't a cached response.
if (self.opts.syncAccumulator && !isCachedResponse) {
self.opts.syncAccumulator.accumulate(data);
// Don't give the store back its own cached data
if (!isCachedResponse) {
client.store.setSyncData(data);
}
// emit synced events