Skip to content

fix: Dequeue messages when committing#4979

Closed
ingoncalves wants to merge 1 commit intoether:developfrom
storytouch:teksto/2620-fix-sync
Closed

fix: Dequeue messages when committing#4979
ingoncalves wants to merge 1 commit intoether:developfrom
storytouch:teksto/2620-fix-sync

Conversation

@ingoncalves
Copy link
Copy Markdown
Contributor

This PR proposes a fix to the issue #4978

Let's try to explain this issue.

After a thorough analysis of the code, we found that the problem occurs in the message management performed by collab_client.js. The messages handler uses a msgQueue queue to store all messages coming from the server. There is also a state control that admits the values ​​IDLE and COMMITING. The synchronization problem occurs when there is a combination of the state equal to COMMITING with the non-empty queue.

Every time a user makes a change to the text, a new changeset is generated, but the changes are not yet applied to the base text, being suspended until confirmation from the server. So, if the state is IDLE (initial value), the user sends a USER_CHANGES message to the server and changes its state to COMITTING.
https://github.com/ether/etherpad-lite/blob/5db0c8d1cfc3f354a5a8badce6d5c3890d428e98/src/static/js/collab_client.js#L151-L158
The server then receives and processes the message, and finally responds to the author user with a message ACCEPT_COMMIT and to the other users with the message NEW_CHANGES. When the user receives an ACCEPT_COMMIT message, he commits the changeset to the base text and sets its status to IDLE again.

It is worth mentioning that when a new message from the server is received, the user checks the message queue. If the queue is not empty, the user queues the message and postpones its processing. The special case is when the user receives a message NEW_CHANGES, where in addition to checking the status of the queue, he also checks if he is during a character composition. If so, the message is also queued.
https://github.com/ether/etherpad-lite/blob/5db0c8d1cfc3f354a5a8badce6d5c3890d428e98/src/static/js/collab_client.js#L222

This mechanism works very quickly and the queue is almost never larger than 1. However, with a slow or problematic connection, the user may be in the COMMITING state waiting for the ACCEPT_COMMIT from the server and, concurrently, he receives messages NEW_CHANGES during a song. In this case, the message will be queued and the status will continue as COMMITING. When receiving ACCEPT_COMMIT, the queue will not be empty and this message will also be queued, without any change of state. In this special condition, ACCEPT_COMMIT will no longer be processed and status will not be changed. Consequently, new changes will not be sent to the server, since the sending only occurs when the file is IDLE.
This loop occurs in the line 102
https://github.com/ether/etherpad-lite/blob/5db0c8d1cfc3f354a5a8badce6d5c3890d428e98/src/static/js/collab_client.js#L94-L105

The solution we propose is to process all messages in the queue whenever the function handleUserChanges is called with state == COMMITING. We add one more condition to this if/else statement, after checking network issues.

//...
} else if (msgQueue.length > 0) {
  dequeueMessages();
} else {
//...

@ingoncalves ingoncalves changed the title [fix] Dequeue messages when committing fix: Dequeue messages when committing Mar 26, 2021
@rhansen
Copy link
Copy Markdown
Member

rhansen commented Mar 28, 2021

Thanks for this! I need to do some studying to understand this change. In the meantime would you split the commit into two:

  1. A commit that factors out the duplicate ACCEPT_COMMIT handling logic into a separate acceptCommit() function.
  2. The rest of your changes.

@rhansen
Copy link
Copy Markdown
Member

rhansen commented Mar 30, 2021

Superseded by #4983.

@rhansen rhansen closed this Mar 30, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants