diff --git a/js/editor/server/pullbox/OperationRouter.js b/js/editor/server/pullbox/OperationRouter.js index 7db2a53a..48995e44 100644 --- a/js/editor/server/pullbox/OperationRouter.js +++ b/js/editor/server/pullbox/OperationRouter.js @@ -59,12 +59,11 @@ define("webodf/editor/server/pullbox/OperationRouter", [], function () { var operationFactory, /**@type{function(!ops.Operation)}*/ playbackFunction, + idleTimeout = null, syncOpsTimeout = null, /**@type{!boolean}*/ isInstantSyncRequested = false, /**@type{!boolean}*/ - isPushingOpsTriggered = false, - /**@type{!boolean}*/ isPlayingUnplayedServerOpSpecs = false, /**@type{!boolean}*/ isSyncCallRunning = false, @@ -90,8 +89,8 @@ define("webodf/editor/server/pullbox/OperationRouter", [], function () { hasPushedModificationOps = false, operationTransformer = new ops.OperationTransformer(), /**@const*/replayTime = 500, - /**@const*/pushingIntervall = 3000, - /**@const*/pullingIntervall = 8000; + /**@const*/syncOpsDelay = 3000, + /**@const*/idleDelay = 5000; function updateHasLocalUnsyncedOpsState() { @@ -254,6 +253,17 @@ runtime.log("Merged: from "+opspecs.length+" to "+result.length+" specs"); var syncedClientOpspecs, syncRequestCallbacksArray; + /** + * @return {undefined} + */ + function startSyncOpsTimeout() { + idleTimeout = null; + syncOpsTimeout = runtime.getWindow().setTimeout(function() { + syncOpsTimeout = null; + syncOps(); + }, syncOpsDelay); + } + if (isSyncCallRunning || hasUnresolvableConflict) { return; } @@ -262,8 +272,8 @@ runtime.log("Merged: from "+opspecs.length+" to "+result.length+" specs"); return; } - // no more timeout or instant pull request in any case - syncOpsTimeout = null; +runtime.log("OperationRouter: sending sync_ops call"); + // no more instant pull request in any case isInstantSyncRequested = false; // set lock isSyncCallRunning = true; @@ -290,7 +300,7 @@ runtime.log("Merged: from "+opspecs.length+" to "+result.length+" specs"); return; } - runtime.log("sync-ops reply: " + responseData); + runtime.log("sync_ops reply: " + responseData); // just new ops? if (response.result === "new_ops") { @@ -307,6 +317,8 @@ runtime.log("Merged: from "+opspecs.length+" to "+result.length+" specs"); } // and note server state lastServerSeq = response.head_seq; + } else { + receiveOpSpecsFromNetwork([], syncRequestCallbacksArray); } } else if (response.result === "added") { runtime.log("All added to server"); @@ -347,10 +359,12 @@ runtime.log("Merged: from "+opspecs.length+" to "+result.length+" specs"); if (isInstantSyncRequested) { syncOps(); } else { - syncOpsTimeout = runtime.getWindow().setTimeout(function() { - syncOpsTimeout = null; - syncOps(); - }, (unsyncedClientOpspecQueue.length === 0) ? pullingIntervall : pushingIntervall); + // nothing on client to sync? + if (unsyncedClientOpspecQueue.length === 0) { + idleTimeout = runtime.getWindow().setTimeout(startSyncOpsTimeout, idleDelay); + } else { + startSyncOpsTimeout(); + } } playUnplayedServerOpSpecs(); } @@ -358,25 +372,20 @@ runtime.log("Merged: from "+opspecs.length+" to "+result.length+" specs"); } function triggerPushingOps() { - if (isSyncCallRunning || isPushingOpsTriggered) { - return; + // disable any idle timeout + if (idleTimeout) { + runtime.clearTimeout(idleTimeout); + idleTimeout = null; } - isPushingOpsTriggered = true; - // disable current pulling timeout - if (syncOpsTimeout) { - runtime.clearTimeout(syncOpsTimeout); - syncOpsTimeout = null; + // enable syncOps timeout, if needed + if (!syncOpsTimeout && !isSyncCallRunning) { +runtime.log("OperationRouter: opsSync requested for pushing"); + syncOpsTimeout = runtime.getWindow().setTimeout(function() { + syncOpsTimeout = null; + syncOps(); + }, syncOpsDelay); } - - // TODO: how stupid! if the pulling timeout was close to done, this will extend it - // solution: split pulling into two timeouts, with second as short as pushing, - // and only cancel the first half - runtime.getWindow().setTimeout(function() { -runtime.log("Pushing activated"); - isPushingOpsTriggered = false; - syncOps(); - }, pushingIntervall); } /** @@ -384,14 +393,23 @@ runtime.log("Pushing activated"); * @return {undefined} */ function requestInstantOpsSync(cb) { + // register callback syncRequestCallbacksQueue.push(cb); - // disable current pulling timeout + // disable any idle timeout + if (idleTimeout) { + runtime.clearTimeout(idleTimeout); + idleTimeout = null; + } + + // disable any syncOps timeout if (syncOpsTimeout) { runtime.clearTimeout(syncOpsTimeout); syncOpsTimeout = null; } +runtime.log("OperationRouter: instant opsSync requested"); + isInstantSyncRequested = true; syncOps(); };