Details
-
Bug
-
Resolution: Unresolved
-
Major
-
None
-
16.10.11
-
None
-
Unknown
-
Description
Steps to reproduce
- Edit a page with the WYSIWYG editor, with realtime collaboration enabled, while nobody else is editing it.
- Wait until the realtime toolbar shows that you are connected.
- Lose the network connection long enough for the WebSocket connection to be closed. For instance, switch the browser offline from its developer tools and wait a few seconds. This closes the connection right away when XWiki is accessed through a host name other than localhost; on localhost the client ignores the browser "offline" event and the connection is closed only by the client watchdog, after about 90 seconds.
- Restore the network connection.
Expected: the editor reconnects to the realtime session and you can continue editing.
Actual: the realtime toolbar stays on "Connecting" until the page is reloaded (see the attached screenshot). The browser console shows a never ending series of NO_SUCH_CHANNEL errors, and the WebSocket frames show ERROR ENOENT "Channel [...] not found".
The editor recovers if another user stays in the realtime session while you are offline.
This was reported as a secondary observation in XWIKI-24799 (on 18.6.0) and reproduced on 18.9.0-SNAPSHOT, which includes the XWIKI-24799 fix: any real connection loss of a user who is editing alone still triggers it.
Cause
The Netflux server deletes a channel when its last user leaves it, so all the channels of the realtime session are gone when a user who was editing alone reconnects. Then:
- The user data synchronization (used to show the other users' carets) rejoins its old channel and the server answers ENOENT. No onError handler is defined, so the error is ignored.
- The WYSIWYG editor fetches the channels again (_beforeReconnecting), gets new channel keys and calls _onAbort() to leave the old realtime session before joining the new one.
- _onAbort() waits for the auto-saver to stop (await this._saver?.stop()). Stopping the saver pushes its state and waits for ChainPad to settle, but the push can't be delivered: it fails with DISCONNECTED and then NO_SUCH_CHANNEL because the old saver channel doesn't exist anymore, and it is retried forever. ChainPad 5.3.0 has its pending message timeout commented out, and netflux-client drops the in-flight messages on reconnect without rejecting them, so this wait never ends.
- As a consequence _onAbort() never returns and _startRealtimeSync() is never called, so the editor never joins the new realtime session.
This was confirmed with logpoints placed right before and right after await this._saver?.stop() in _onAbort(): only the first one is reached. The wait on the saver was added by XWIKI-23228, so the problem is present since 16.10.11, 17.4.4 and 17.6.0-rc-1.
Other problems observed
- _onAbort() calls setRealtimeEnabled(false) without awaiting it. It broadcasts on the deleted loader channel, which leads to an Uncaught (in promise) NO_SUCH_CHANNEL error.
- With two users, the user who reconnects isn't added back to the saver and loader channels: their user count stays at 1 on the server.
- The realtime wiki editor was not tested, but its code has related problems: updateKeys() falls back to undeclared variables, and onReady starts a new user data synchronization and a new saver on each reconnect without stopping the previous ones.
Possible fix
- Don't wait for the saver to settle when the connection is closed, or limit that wait with a timeout.
- Refresh the channel key of the user data synchronization on reconnect (e.g. with a beforeReconnecting handler), or restart it from the editor.
- Handle the join errors (onError) on the ChainPad-Netflux configurations, e.g. by fetching the channels again and restarting the realtime session.
Attachments
Issue Links
- is caused by
-
XWIKI-23228 When clicking "Done", the realtime editor sometimes asks if the user wants to leave the page
-
- Closed
-
- relates to
-
XWIKI-24799 Netflux server-side idle timeout is hardcoded at 65s and kills healthy realtime sessions in throttled background tabs (server-side counterpart of XWIKI-23928)
-
- Closed
-