From d72a70396a7d2d1f0a9572d7b2677e279b389da4 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Tue, 28 Aug 2018 14:54:54 +0200 Subject: [PATCH 1/5] Pass through PREPARED state after error, when keepalive returns succes. This is according to the state diagram in client.js. This will show a spinner at the bottom of a room again while the catchup sync is in progress, which seems to have broken at some point. --- src/sync.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/sync.js b/src/sync.js index 4aa2d24822f..6bf2e324694 100644 --- a/src/sync.js +++ b/src/sync.js @@ -780,6 +780,13 @@ SyncApi.prototype._onSyncError = function(err, syncOptions) { // instead, so that clients can observe this state // if they wish. this._startKeepAlives().then(() => { + if (this.getSyncState() == 'ERROR') { + this._updateSyncState("PREPARED", { + oldSyncToken: null, + nextSyncToken: null, + catchingUp: true, + }); + } this._sync(syncOptions); }); From d837ae64acfcfbdf2ca6683938533086f0966d65 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Thu, 30 Aug 2018 15:23:14 +0200 Subject: [PATCH 2/5] triple = --- src/sync.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sync.js b/src/sync.js index 6bf2e324694..3b8d031e28b 100644 --- a/src/sync.js +++ b/src/sync.js @@ -780,7 +780,7 @@ SyncApi.prototype._onSyncError = function(err, syncOptions) { // instead, so that clients can observe this state // if they wish. this._startKeepAlives().then(() => { - if (this.getSyncState() == 'ERROR') { + if (this.getSyncState() === 'ERROR') { this._updateSyncState("PREPARED", { oldSyncToken: null, nextSyncToken: null, From 0d23d047fccbbf6ec1c780ad5268640082151802 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Thu, 30 Aug 2018 15:37:00 +0200 Subject: [PATCH 3/5] use CATCHUP state after ERROR before going back to SYNCING --- src/client.js | 16 +++++++++++----- src/sync.js | 2 +- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/client.js b/src/client.js index 1f3a4813072..3e076480c13 100644 --- a/src/client.js +++ b/src/client.js @@ -3504,6 +3504,12 @@ module.exports.CRYPTO_ENABLED = CRYPTO_ENABLED; * a state of SYNCING. This is the equivalent of "syncComplete" in the * previous API. * + *
  • CATCHUP: The client has detected the connection to the server might be + * available again and will now try to do a sync again. As this sync might take + * a long time (depending how long ago was last synced, and general server + * performance) the client is put in this mode so the UI can reflect trying + * to catch up with the server after losing connection.
  • + * *
  • SYNCING : The client is currently polling for new events from the server. * This will be called after processing latest events from a sync.
  • * @@ -3527,11 +3533,11 @@ module.exports.CRYPTO_ENABLED = CRYPTO_ENABLED; * +---->STOPPED * | * +----->PREPARED -------> SYNCING <--+ - * | ^ | ^ | - * | | | | | - * | | V | | - * null ------+ | +--------RECONNECTING | - * | | V | + * | ^ | ^ | + * | CATCHUP ----------+ | | | + * | ^ V | | + * null ------+ | +------- RECONNECTING | + * | V V | * +------->ERROR ---------------------+ * * NB: 'null' will never be emitted by this event. diff --git a/src/sync.js b/src/sync.js index 3b8d031e28b..1a4566db291 100644 --- a/src/sync.js +++ b/src/sync.js @@ -781,7 +781,7 @@ SyncApi.prototype._onSyncError = function(err, syncOptions) { // if they wish. this._startKeepAlives().then(() => { if (this.getSyncState() === 'ERROR') { - this._updateSyncState("PREPARED", { + this._updateSyncState("CATCHUP", { oldSyncToken: null, nextSyncToken: null, catchingUp: true, From 1239485b300b71aacb479f59ebf0c58cb4b23af0 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Thu, 30 Aug 2018 15:42:15 +0200 Subject: [PATCH 4/5] fix test --- spec/unit/matrix-client.spec.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/unit/matrix-client.spec.js b/spec/unit/matrix-client.spec.js index 8ef22f6b018..2fc5d2cf0f7 100644 --- a/spec/unit/matrix-client.spec.js +++ b/spec/unit/matrix-client.spec.js @@ -380,7 +380,7 @@ describe("MatrixClient", function() { client.startClient(); }); - it("should transition ERROR -> PREPARED after /sync if prev failed", + it("should transition ERROR -> CATCHUP after /sync if prev failed", function(done) { const expectedStates = []; acceptKeepalives = false; @@ -403,7 +403,7 @@ describe("MatrixClient", function() { expectedStates.push(["RECONNECTING", null]); expectedStates.push(["ERROR", "RECONNECTING"]); - expectedStates.push(["PREPARED", "ERROR"]); + expectedStates.push(["CATCHUP", "ERROR"]); client.on("sync", syncChecker(expectedStates, done)); client.startClient(); }); From f0095611bcbd84612fc1e3dc32aee18237d2457b Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Tue, 4 Sep 2018 16:38:46 +0200 Subject: [PATCH 5/5] add new CATCHUP state as breaking change --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b7a80983411..37f4f45845f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ BREAKING CHANGE --------------- * `MatrixClient::startClient` now returns a Promise. No method should be called on the client before that promise resolves. Before this method didn't return anything. + * A new `CATCHUP` sync state, emitted by `MatrixClient#"sync"` and returned by `MatrixClient::getSyncState()`, when doing initial sync after the `ERROR` state. See `MatrixClient` documentation for details. Changes in [0.11.0](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v0.11.0) (TDB) ==================================================================================================