Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
fix(reconnect): keep baseVersionEtag during reconnect
`this.$syncService` is cleared during the `close` method.

However we need the `baseVersionEtag` to ensure the editing session
on the server
is still in sync with our local ydoc.

Signed-off-by: Max <[email protected]>
  • Loading branch information
max-nextcloud authored and backportbot[bot] committed Jul 3, 2024
commit a763c762580b11ad15986fc819ff026280a8f853
37 changes: 23 additions & 14 deletions cypress/e2e/sync.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,22 +64,11 @@ describe('Sync', () => {
})

it('recovers from a short lost connection', () => {
let reconnect = false
cy.intercept('**/apps/text/session/*/*', (req) => {
if (reconnect) {
req.continue()
req.alias = 'alive'
} else {
req.destroy()
req.alias = 'dead'
}
}).as('sessionRequests')
cy.intercept('**/apps/text/session/*/*', req => req.destroy()).as('dead')
cy.wait('@dead', { timeout: 30000 })
cy.get('#editor-container .document-status', { timeout: 30000 })
.should('contain', 'Document could not be loaded.')
.then(() => {
reconnect = true
})
cy.intercept('**/apps/text/session/*/*', req => req.continue()).as('alive')
cy.wait('@alive', { timeout: 30000 })
cy.intercept({ method: 'POST', url: '**/apps/text/session/*/sync' })
.as('syncAfterRecovery')
Expand All @@ -97,6 +86,26 @@ describe('Sync', () => {
.should('include', 'after the lost connection')
})

it('reconnects via button after a short lost connection', () => {
cy.intercept('**/apps/text/session/*/*', req => req.destroy()).as('dead')
cy.wait('@dead', { timeout: 30000 })
cy.get('#editor-container .document-status', { timeout: 30000 })
.should('contain', 'Document could not be loaded.')
cy.get('#editor-container .document-status')
.find('.button.primary').click()
cy.intercept('**/apps/text/session/*/*', req => {
if (req.url.endsWith('create')) {
req.alias = 'create'
}
req.continue()
}).as('alive')
cy.wait('@alive', { timeout: 30000 })
cy.wait('@create', { timeout: 10000 })
.its('request.body')
.should('have.property', 'baseVersionEtag')
.should('not.be.empty')
})

it('recovers from a lost and closed connection', () => {
let reconnect = false
cy.intercept('**/apps/text/session/*/*', (req) => {
Expand Down Expand Up @@ -128,7 +137,7 @@ describe('Sync', () => {
.should('include', 'after the lost connection')
})

it('shows warning when document session got cleaned up', () => {
it('asks to reload page when document session got cleaned up', () => {
cy.get('.save-status button')
.click()
cy.wait('@save')
Expand Down
5 changes: 3 additions & 2 deletions src/components/Editor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@ export default {
guestName,
shareToken: this.shareToken,
filePath: this.relativePath,
baseVersionEtag: this.$syncService?.baseVersionEtag,
baseVersionEtag: this.$baseVersionEtag,
forceRecreate: this.forceRecreate,
serialize: this.isRichEditor
? (content) => createMarkdownSerializer(this.$editor.schema).serialize(content ?? this.$editor.state.doc)
Expand Down Expand Up @@ -493,7 +493,7 @@ export default {
})
},

onLoaded({ documentSource, documentState }) {
onLoaded({ document, documentSource, documentState }) {
if (documentState) {
applyDocumentState(this.$ydoc, documentState, this.$providers[0])
// distribute additional state that may exist locally
Expand All @@ -506,6 +506,7 @@ export default {
this.setInitialYjsState(documentSource, { isRichEditor: this.isRichEditor })
}

this.$baseVersionEtag = document.baseVersionEtag
this.hasConnectionIssue = false
const language = extensionHighlight[this.fileExtension] || this.fileExtension;

Expand Down