fix: buffer operations in Stale/StaleWithBuffer instead of throwing (#6342)
When 5+ users edit concurrently, revision gaps trigger the Stale state which throws 'Ignored server-side change.' on incoming operations. This causes document divergence, silent data corruption, and eventually force-resets that discard local edits. Changes: - Stale/StaleWithBuffer.applyServer: buffer incoming operations instead of throwing, apply them sequentially after missing ops arrive - Stale.applyClient: carry pendingOps to StaleWithBuffer on transition - editor-socketio-server: retry-based force-reset (3 failures) instead of immediate nuclear reset on any OT error - hex2rgb: defensive null checks for old non-hex color records Signed-off-by: bxff <51504045+bxff@users.noreply.github.com>
This commit is contained in:
@@ -51,14 +51,23 @@ EditorSocketIOServer.prototype.addClient = function (socket) {
|
||||
self.onOperation(socket, revision, operation, selection);
|
||||
if (typeof self.operationCallback === 'function')
|
||||
self.operationCallback(socket, operation);
|
||||
socket._opRetries = 0;
|
||||
} catch (err) {
|
||||
logger.error("Operation error from client " + socket.id + ": " + err.message);
|
||||
if (!socket._opRetries) socket._opRetries = 0;
|
||||
socket._opRetries++;
|
||||
setTimeout(function() {
|
||||
var docOut = {
|
||||
str: self.document,
|
||||
revision: self.operations.length,
|
||||
clients: self.users,
|
||||
force: true
|
||||
clients: self.users
|
||||
};
|
||||
// Only force-reset after 3 consecutive failures as a last resort.
|
||||
// Without force:true, the client will use its Stale recovery to resync.
|
||||
if (socket._opRetries >= 3) {
|
||||
docOut.force = true;
|
||||
socket._opRetries = 0;
|
||||
}
|
||||
socket.emit('doc', docOut);
|
||||
}, 100);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user