From 9a8219d1081042168a7e736106e40528d62617e8 Mon Sep 17 00:00:00 2001 From: Max Date: Tue, 16 Jul 2024 18:23:23 +0200 Subject: [PATCH] fix(sync): reuse open connection Do not attempt to create a new connection if there already is one and it is not closed. If no messages are received for 30 seconds yjs will open a new websocket. Since we do not close the connection anymore from the websocket polyfill we also do not need to open it. If the network connection has gone down creating a new connection will fail anyway. Once it comes back we will know if the session is still valid. Then we can either continue using it or reconnect. This is part of #6050. Signed-off-by: Max --- cypress/e2e/sync.spec.js | 6 ++++++ src/services/SyncService.js | 5 ++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/cypress/e2e/sync.spec.js b/cypress/e2e/sync.spec.js index 715861bf65d..11f17f41d06 100644 --- a/cypress/e2e/sync.spec.js +++ b/cypress/e2e/sync.spec.js @@ -111,6 +111,7 @@ describe('Sync', () => { it('recovers from a lost and closed connection', () => { let reconnect = false + // block all requests until the session is closed and reopened cy.intercept('**/apps/text/session/*/*', (req) => { if (req.url.includes('close') || req.url.includes('create') || reconnect) { req.continue() @@ -125,6 +126,11 @@ describe('Sync', () => { cy.get('#editor-container .document-status', { timeout: 30000 }) .should('contain', 'Document could not be loaded.') + // Reconnect button works - it closes and reopens the session + cy.get('#editor-container .document-status a.button') + .contains('Reconnect') + .click() + cy.wait('@syncAfterRecovery', { timeout: 60000 }) cy.get('#editor-container .document-status', { timeout: 30000 }) diff --git a/src/services/SyncService.js b/src/services/SyncService.js index 9db0a1050fa..c13481d0b72 100644 --- a/src/services/SyncService.js +++ b/src/services/SyncService.js @@ -107,6 +107,10 @@ class SyncService { } async open({ fileId, initialSession }) { + if (this.#connection && !this.#connection.isClosed) { + // We're already connected. + return + } const onChange = ({ sessions }) => { this.sessions = sessions } @@ -116,7 +120,6 @@ class SyncService { ? Promise.resolve(new Connection({ data: initialSession }, {})) : this._api.open({ fileId, baseVersionEtag: this.baseVersionEtag }) .catch(error => this._emitError(error)) - this.#connection = await connect if (!this.#connection) { this.off('change', onChange)