Skip to content

Commit

Permalink
fix(sync): keep queue around during reconnects
Browse files Browse the repository at this point in the history
When yjs does not receive awareness updates
it will close and reopen the websocket.
Keep the content of the queue, i.e. the outgoing steps
so they can be send out once the connection is back.

Signed-off-by: Max <max@nextcloud.com>
  • Loading branch information
max-nextcloud committed Dec 11, 2023
1 parent 045391f commit 2db66d5
Show file tree
Hide file tree
Showing 3 changed files with 7 additions and 2 deletions.
2 changes: 2 additions & 0 deletions cypress/e2e/api/SyncServiceProvider.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ describe('Sync service provider', function() {
* @param {object} ydoc Yjs document
*/
function createProvider(ydoc) {
const queue = []
const syncService = new SyncService({
serialize: () => 'Serialized',
getDocumentState: () => null,
Expand All @@ -70,6 +71,7 @@ describe('Sync service provider', function() {
syncService,
fileId,
initialSession: null,
queue,
disableBc: true,
})
}
Expand Down
2 changes: 2 additions & 0 deletions src/components/Editor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,7 @@ export default {
},
created() {
this.$ydoc = new Doc()
this.$queue = []
// The following can be useful for debugging ydoc updates
// this.$ydoc.on('update', function(update, origin, doc, tr) {
// console.debug('ydoc update', update, origin, doc, tr)
Expand Down Expand Up @@ -381,6 +382,7 @@ export default {
ydoc: this.$ydoc,
syncService: this.$syncService,
fileId: this.fileId,
queue: this.$queue,
initialSession: this.initialSession,
})
this.$providers.push(syncServiceProvider)
Expand Down
5 changes: 3 additions & 2 deletions src/services/SyncServiceProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,16 @@ import { logger } from '../helpers/logger.js'
* @param {object} options.ydoc - the Ydoc
* @param {object} options.syncService - sync service to build upon
* @param {number} options.fileId - file id of the file to open
* @param {number} options.queue - queue for outgoing steps
* @param {object} options.initialSession - initialSession to start from
* @param {boolean} options.disableBc - disable broadcast channel synchronization (default: disabled in debug mode, enabled otherwise)
*/
export default function createSyncServiceProvider({ ydoc, syncService, fileId, initialSession, disableBc }) {
export default function createSyncServiceProvider({ ydoc, syncService, fileId, initialSession, queue, disableBc }) {
if (!fileId) {
// We need a file id as a unique identifier for y.js as otherwise state might leak between different files
throw new Error('fileId is required')
}
const WebSocketPolyfill = initWebSocketPolyfill(syncService, fileId, initialSession)
const WebSocketPolyfill = initWebSocketPolyfill(syncService, fileId, initialSession, queue)
disableBc = disableBc ?? !!window?._oc_debug
const websocketProvider = new WebsocketProvider(
'ws://localhost:1234',
Expand Down

0 comments on commit 2db66d5

Please sign in to comment.