You've already forked matrix-js-sdk
mirror of
https://github.com/matrix-org/matrix-js-sdk.git
synced 2025-11-26 17:03:12 +03:00
Automatically reconnect sessions when sliding sync expires them
This can happen when you close your laptop overnight, as the server will not hold onto in-memory resources for your connection indefinitely. When this happen, the server will HTTP 400 you with "session expired". At this point, it is no longer safe to remember anything and you must forget everything and resend any sticky parameters. This commit does the sticky parameters and re-establishes the connection, but it may need additional work to make the JS SDK forget now invalid data.
This commit is contained in:
@@ -694,6 +694,26 @@ export class SlidingSync extends TypedEventEmitter<SlidingSyncEvent, SlidingSync
|
||||
this.removeAllListeners(SlidingSyncEvent.RoomData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Re-setup this connection e.g in the event of an expired session.
|
||||
*/
|
||||
private resetup(): void {
|
||||
logger.warn("SlidingSync: resetting connection info");
|
||||
// any pending txn ID defers will be forgotten already by the server, so clear them out
|
||||
this.txnIdDefers.forEach((d) => {
|
||||
d.reject(d.txnId);
|
||||
});
|
||||
this.txnIdDefers = [];
|
||||
// resend sticky params and de-confirm all subscriptions
|
||||
this.lists.forEach((l) => {
|
||||
l.setModified(true);
|
||||
});
|
||||
this.confirmedRoomSubscriptions = new Set<string>(); // leave desired ones alone though!
|
||||
// reset the connection as we might be wedged
|
||||
this.needsResend = true;
|
||||
this.pendingReq?.abort();
|
||||
}
|
||||
|
||||
/**
|
||||
* Start syncing with the server. Blocks until stopped.
|
||||
*/
|
||||
@@ -732,7 +752,6 @@ export class SlidingSync extends TypedEventEmitter<SlidingSyncEvent, SlidingSync
|
||||
}
|
||||
this.pendingReq = this.client.slidingSync(reqBody, this.proxyBaseUrl);
|
||||
resp = await this.pendingReq;
|
||||
logger.debug(resp);
|
||||
currentPos = resp.pos;
|
||||
// update what we think we're subscribed to.
|
||||
for (const roomId of newSubscriptions) {
|
||||
@@ -770,7 +789,15 @@ export class SlidingSync extends TypedEventEmitter<SlidingSyncEvent, SlidingSync
|
||||
null,
|
||||
err,
|
||||
);
|
||||
await sleep(3000);
|
||||
if (err.httpStatus === 400) {
|
||||
// session probably expired TODO: assign an errcode
|
||||
// so drop state and re-request
|
||||
this.resetup();
|
||||
currentPos = undefined;
|
||||
await sleep(50); // in case the 400 was for something else; don't tightloop
|
||||
continue;
|
||||
}
|
||||
await sleep(5000);
|
||||
} else if (this.needsResend || err === "aborted") {
|
||||
// don't sleep as we caused this error by abort()ing the request.
|
||||
// we check for 'aborted' because that's the error Jest returns and without it
|
||||
@@ -778,7 +805,7 @@ export class SlidingSync extends TypedEventEmitter<SlidingSyncEvent, SlidingSync
|
||||
continue;
|
||||
} else {
|
||||
logger.error(err);
|
||||
await sleep(3000);
|
||||
await sleep(5000);
|
||||
}
|
||||
}
|
||||
if (!resp) {
|
||||
|
||||
Reference in New Issue
Block a user