You've already forked matrix-js-sdk
mirror of
https://github.com/matrix-org/matrix-js-sdk.git
synced 2025-11-28 05:03:59 +03:00
Merge branch 'develop' into kegan/indexeddb
This commit is contained in:
@@ -3042,21 +3042,26 @@ module.exports.CRYPTO_ENABLED = CRYPTO_ENABLED;
|
|||||||
/**
|
/**
|
||||||
* Fires whenever the SDK's syncing state is updated. The state can be one of:
|
* Fires whenever the SDK's syncing state is updated. The state can be one of:
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>PREPARED : The client has synced with the server at least once and is
|
*
|
||||||
|
* <li>PREPARED: The client has synced with the server at least once and is
|
||||||
* ready for methods to be called on it. This will be immediately followed by
|
* ready for methods to be called on it. This will be immediately followed by
|
||||||
* a state of SYNCING. <i>This is the equivalent of "syncComplete" in the
|
* a state of SYNCING. <i>This is the equivalent of "syncComplete" in the
|
||||||
* previous API.</i></li>
|
* previous API.</i></li>
|
||||||
|
*
|
||||||
* <li>SYNCING : The client is currently polling for new events from the server.
|
* <li>SYNCING : The client is currently polling for new events from the server.
|
||||||
* This will be called <i>after</i> processing latest events from a sync.</li>
|
* This will be called <i>after</i> processing latest events from a sync.</li>
|
||||||
|
*
|
||||||
* <li>ERROR : The client has had a problem syncing with the server. If this is
|
* <li>ERROR : The client has had a problem syncing with the server. If this is
|
||||||
* called <i>before</i> PREPARED then there was a problem performing the initial
|
* called <i>before</i> PREPARED then there was a problem performing the initial
|
||||||
* sync. If this is called <i>after</i> PREPARED then there was a problem polling
|
* sync. If this is called <i>after</i> PREPARED then there was a problem polling
|
||||||
* the server for updates. This may be called multiple times even if the state is
|
* the server for updates. This may be called multiple times even if the state is
|
||||||
* already ERROR. <i>This is the equivalent of "syncError" in the previous
|
* already ERROR. <i>This is the equivalent of "syncError" in the previous
|
||||||
* API.</i></li>
|
* API.</i></li>
|
||||||
* <li>RECONNECTING: The sync connedtion has dropped, but not in a way that should
|
*
|
||||||
* be considered erroneous.
|
* <li>RECONNECTING: The sync connection has dropped, but not (yet) in a way that
|
||||||
|
* should be considered erroneous.
|
||||||
* </li>
|
* </li>
|
||||||
|
*
|
||||||
* <li>STOPPED: The client has stopped syncing with server due to stopClient
|
* <li>STOPPED: The client has stopped syncing with server due to stopClient
|
||||||
* being called.
|
* being called.
|
||||||
* </li>
|
* </li>
|
||||||
@@ -3066,32 +3071,46 @@ module.exports.CRYPTO_ENABLED = CRYPTO_ENABLED;
|
|||||||
* +---->STOPPED
|
* +---->STOPPED
|
||||||
* |
|
* |
|
||||||
* +----->PREPARED -------> SYNCING <--+
|
* +----->PREPARED -------> SYNCING <--+
|
||||||
* | ^ ^ |
|
* | ^ | ^ |
|
||||||
* | | | |
|
* | | | | |
|
||||||
* | | V |
|
* | | V | |
|
||||||
* null ------+ | +-RECONNECTING<-+ |
|
* null ------+ | +--------RECONNECTING |
|
||||||
* | | V |
|
* | | V |
|
||||||
* +------->ERROR ---------------------+
|
* +------->ERROR ---------------------+
|
||||||
*
|
*
|
||||||
* NB: 'null' will never be emitted by this event.
|
* NB: 'null' will never be emitted by this event.
|
||||||
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
* Transitions:
|
* Transitions:
|
||||||
* <ul>
|
* <ul>
|
||||||
|
*
|
||||||
* <li><code>null -> PREPARED</code> : Occurs when the initial sync is completed
|
* <li><code>null -> PREPARED</code> : Occurs when the initial sync is completed
|
||||||
* first time. This involves setting up filters and obtaining push rules.
|
* first time. This involves setting up filters and obtaining push rules.
|
||||||
|
*
|
||||||
* <li><code>null -> ERROR</code> : Occurs when the initial sync failed first time.
|
* <li><code>null -> ERROR</code> : Occurs when the initial sync failed first time.
|
||||||
|
*
|
||||||
* <li><code>ERROR -> PREPARED</code> : Occurs when the initial sync succeeds
|
* <li><code>ERROR -> PREPARED</code> : Occurs when the initial sync succeeds
|
||||||
* after previously failing.
|
* after previously failing.
|
||||||
|
*
|
||||||
* <li><code>PREPARED -> SYNCING</code> : Occurs immediately after transitioning
|
* <li><code>PREPARED -> SYNCING</code> : Occurs immediately after transitioning
|
||||||
* to PREPARED. Starts listening for live updates rather than catching up.
|
* to PREPARED. Starts listening for live updates rather than catching up.
|
||||||
* <li><code>SYNCING -> ERROR</code> : Occurs the first time a client cannot perform a
|
*
|
||||||
* live update.
|
* <li><code>SYNCING -> RECONNECTING</code> : Occurs when the live update fails.
|
||||||
|
*
|
||||||
|
* <li><code>RECONNECTING -> RECONNECTING</code> : Can occur if the update calls
|
||||||
|
* continue to fail, but the keepalive calls (to /versions) succeed.
|
||||||
|
*
|
||||||
|
* <li><code>RECONNECTING -> ERROR</code> : Occurs when the keepalive call also fails
|
||||||
|
*
|
||||||
* <li><code>ERROR -> SYNCING</code> : Occurs when the client has performed a
|
* <li><code>ERROR -> SYNCING</code> : Occurs when the client has performed a
|
||||||
* live update after having previously failed.
|
* live update after having previously failed.
|
||||||
* <li><code>ERROR -> ERROR</code> : Occurs when the client has failed to sync
|
*
|
||||||
|
* <li><code>ERROR -> ERROR</code> : Occurs when the client has failed to keepalive
|
||||||
* for a second time or more.</li>
|
* for a second time or more.</li>
|
||||||
|
*
|
||||||
* <li><code>SYNCING -> SYNCING</code> : Occurs when the client has performed a live
|
* <li><code>SYNCING -> SYNCING</code> : Occurs when the client has performed a live
|
||||||
* update. This is called <i>after</i> processing.</li>
|
* update. This is called <i>after</i> processing.</li>
|
||||||
|
*
|
||||||
* <li><code>* -> STOPPED</code> : Occurs once the client has stopped syncing or
|
* <li><code>* -> STOPPED</code> : Occurs once the client has stopped syncing or
|
||||||
* trying to sync after stopClient has been called.</li>
|
* trying to sync after stopClient has been called.</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
@@ -3117,6 +3136,9 @@ module.exports.CRYPTO_ENABLED = CRYPTO_ENABLED;
|
|||||||
* will become the 'since' token for the next call to /sync. Only present if
|
* will become the 'since' token for the next call to /sync. Only present if
|
||||||
* <code>state=PREPARED</code> or <code>state=SYNCING</code>.
|
* <code>state=PREPARED</code> or <code>state=SYNCING</code>.
|
||||||
*
|
*
|
||||||
|
* @param {boolean} data.catchingUp True if we are working our way through a
|
||||||
|
* backlog of events after connecting. Only present if <code>state=SYNCING</code>.
|
||||||
|
*
|
||||||
* @example
|
* @example
|
||||||
* matrixClient.on("sync", function(state, prevState, data) {
|
* matrixClient.on("sync", function(state, prevState, data) {
|
||||||
* switch (state) {
|
* switch (state) {
|
||||||
|
|||||||
41
src/sync.js
41
src/sync.js
@@ -77,6 +77,7 @@ function SyncApi(client, opts) {
|
|||||||
this._peekRoomId = null;
|
this._peekRoomId = null;
|
||||||
this._currentSyncRequest = null;
|
this._currentSyncRequest = null;
|
||||||
this._syncState = null;
|
this._syncState = null;
|
||||||
|
this._catchingUp = false;
|
||||||
this._running = false;
|
this._running = false;
|
||||||
this._keepAliveTimer = null;
|
this._keepAliveTimer = null;
|
||||||
this._connectionReturnedDefer = null;
|
this._connectionReturnedDefer = null;
|
||||||
@@ -487,9 +488,30 @@ SyncApi.prototype._sync = function(syncOptions) {
|
|||||||
|
|
||||||
const syncToken = client.store.getSyncToken();
|
const syncToken = client.store.getSyncToken();
|
||||||
|
|
||||||
|
let pollTimeout = this.opts.pollTimeout;
|
||||||
|
|
||||||
|
if (this.getSyncState() !== 'SYNCING' || this._catchingUp) {
|
||||||
|
// unless we are happily syncing already, we want the server to return
|
||||||
|
// as quickly as possible, even if there are no events queued. This
|
||||||
|
// serves two purposes:
|
||||||
|
//
|
||||||
|
// * When the connection dies, we want to know asap when it comes back,
|
||||||
|
// so that we can hide the error from the user. (We don't want to
|
||||||
|
// have to wait for an event or a timeout).
|
||||||
|
//
|
||||||
|
// * We want to know if the server has any to_device messages queued up
|
||||||
|
// for us. We do that by calling it with a zero timeout until it
|
||||||
|
// doesn't give us any more to_device messages.
|
||||||
|
this._catchingUp = true;
|
||||||
|
pollTimeout = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// normal timeout= plus buffer time
|
||||||
|
const clientSideTimeoutMs = pollTimeout + BUFFER_PERIOD_MS;
|
||||||
|
|
||||||
const qps = {
|
const qps = {
|
||||||
filter: filterId,
|
filter: filterId,
|
||||||
timeout: this.opts.pollTimeout,
|
timeout: pollTimeout,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (syncToken) {
|
if (syncToken) {
|
||||||
@@ -527,9 +549,6 @@ SyncApi.prototype._sync = function(syncOptions) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// normal timeout= plus buffer time
|
|
||||||
const clientSideTimeoutMs = this.opts.pollTimeout + BUFFER_PERIOD_MS;
|
|
||||||
|
|
||||||
if (!isCachedResponse) {
|
if (!isCachedResponse) {
|
||||||
debuglog('Starting sync since=' + syncToken);
|
debuglog('Starting sync since=' + syncToken);
|
||||||
this._currentSyncRequest = client._http.authedRequest(
|
this._currentSyncRequest = client._http.authedRequest(
|
||||||
@@ -564,6 +583,7 @@ SyncApi.prototype._sync = function(syncOptions) {
|
|||||||
const syncEventData = {
|
const syncEventData = {
|
||||||
oldSyncToken: syncToken,
|
oldSyncToken: syncToken,
|
||||||
nextSyncToken: data.next_batch,
|
nextSyncToken: data.next_batch,
|
||||||
|
catchingUp: self._catchingUp,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!syncOptions.hasSyncedBefore) {
|
if (!syncOptions.hasSyncedBefore) {
|
||||||
@@ -691,7 +711,9 @@ SyncApi.prototype._processSyncResponse = function(syncToken, data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// handle to-device events
|
// handle to-device events
|
||||||
if (data.to_device && utils.isArray(data.to_device.events)) {
|
if (data.to_device && utils.isArray(data.to_device.events) &&
|
||||||
|
data.to_device.events.length > 0
|
||||||
|
) {
|
||||||
data.to_device.events
|
data.to_device.events
|
||||||
.map(client.getEventMapper())
|
.map(client.getEventMapper())
|
||||||
.forEach(
|
.forEach(
|
||||||
@@ -712,6 +734,9 @@ SyncApi.prototype._processSyncResponse = function(syncToken, data) {
|
|||||||
client.emit("toDeviceEvent", toDeviceEvent);
|
client.emit("toDeviceEvent", toDeviceEvent);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
} else {
|
||||||
|
// no more to-device events: we can stop polling with a short timeout.
|
||||||
|
this._catchingUp = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// the returned json structure is a bit crap, so make it into a
|
// the returned json structure is a bit crap, so make it into a
|
||||||
@@ -917,7 +942,7 @@ SyncApi.prototype._processSyncResponse = function(syncToken, data) {
|
|||||||
* @param {number} delay How long to delay until the first poll.
|
* @param {number} delay How long to delay until the first poll.
|
||||||
* defaults to a short, randomised interval (to prevent
|
* defaults to a short, randomised interval (to prevent
|
||||||
* tightlooping if /versions succeeds but /sync etc. fail).
|
* tightlooping if /versions succeeds but /sync etc. fail).
|
||||||
* @return {promise}
|
* @return {promise} which resolves once the connection returns
|
||||||
*/
|
*/
|
||||||
SyncApi.prototype._startKeepAlives = function(delay) {
|
SyncApi.prototype._startKeepAlives = function(delay) {
|
||||||
if (delay === undefined) {
|
if (delay === undefined) {
|
||||||
@@ -943,7 +968,11 @@ SyncApi.prototype._startKeepAlives = function(delay) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Make a dummy call to /_matrix/client/versions, to see if the HS is
|
||||||
|
* reachable.
|
||||||
*
|
*
|
||||||
|
* On failure, schedules a call back to itself. On success, resolves
|
||||||
|
* this._connectionReturnedDefer.
|
||||||
*/
|
*/
|
||||||
SyncApi.prototype._pokeKeepAlive = function() {
|
SyncApi.prototype._pokeKeepAlive = function() {
|
||||||
const self = this;
|
const self = this;
|
||||||
|
|||||||
Reference in New Issue
Block a user