You've already forked matrix-js-sdk
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:
@@ -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;
|
||||
|
@@ -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() {
|
||||
|
@@ -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.
|
||||
|
@@ -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.
|
||||
|
56
src/sync.js
56
src/sync.js
@@ -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
|
||||
|
Reference in New Issue
Block a user