Commit 8eefe0c5 authored by Roque's avatar Roque

erp5_web_monitoring: new sync lock to prevent sync from different tabs

parent 336d1714
...@@ -62,7 +62,6 @@ ...@@ -62,7 +62,6 @@
.onEvent('click', function (event) { .onEvent('click', function (event) {
var gadget = this, var gadget = this,
sync_start_time,
success = true, success = true,
element = gadget.element.querySelector("#destroyOPML"); element = gadget.element.querySelector("#destroyOPML");
...@@ -100,24 +99,6 @@ ...@@ -100,24 +99,6 @@
return gadget.notifySubmitting() return gadget.notifySubmitting()
.push(function () { .push(function () {
return gadget.getSetting('sync_start_time');
})
.push(function (start_time) {
sync_start_time = start_time;
return gadget.getSetting('latest_sync_time');
})
.push(function (finish_time) {
if (finish_time - sync_start_time < 0) {
// sync is running, cannot remove OPML now
success = false;
return RSVP.all([
gadget.notifySubmitted({
message: 'Cannot destroy now, please wait until background ' +
'sync is finished',
status: 'error'
})
]);
}
element.setAttribute("disabled", "disabled"); element.setAttribute("disabled", "disabled");
return gadget.jio_allDocs({ return gadget.jio_allDocs({
query: 'portal_type: "opml"', query: 'portal_type: "opml"',
...@@ -125,13 +106,11 @@ ...@@ -125,13 +106,11 @@
}) })
.push(function (result) { .push(function (result) {
return RSVP.all([ return RSVP.all([
gadget.setSetting('sync_lock', true),
removeAllOPML(result) removeAllOPML(result)
]); ]);
}) })
.push(function () { .push(function () {
return RSVP.all([ return RSVP.all([
gadget.setSetting('sync_lock', false),
gadget.notifySubmitted({ gadget.notifySubmitted({
message: 'All OPML removed', message: 'All OPML removed',
status: 'success' status: 'success'
...@@ -139,7 +118,6 @@ ...@@ -139,7 +118,6 @@
]); ]);
}, function () { }, function () {
success = false; success = false;
return gadget.setSetting('sync_lock', false);
}); });
}) })
.push(function () { .push(function () {
......
...@@ -232,7 +232,7 @@ ...@@ -232,7 +232,7 @@
</item> </item>
<item> <item>
<key> <string>actor</string> </key> <key> <string>actor</string> </key>
<value> <string>zope</string> </value> <value> <unicode>zope</unicode> </value>
</item> </item>
<item> <item>
<key> <string>comment</string> </key> <key> <string>comment</string> </key>
...@@ -246,7 +246,7 @@ ...@@ -246,7 +246,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>971.42397.40766.62515</string> </value> <value> <string>1012.23628.37695.12441</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -266,7 +266,7 @@ ...@@ -266,7 +266,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1542303383.28</float> <float>1699538392.28</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
/*global window, rJS, jIO, FormData, XMLHttpRequestProgressEvent */ /*global window, rJS, jIO, FormData, AbortController, RSVP, navigator */
/*jslint indent: 2, maxerr: 3 */ /*jslint indent: 2, maxerr: 3 */
(function (window, rJS, jIO) { (function (window, rJS, jIO) {
"use strict"; "use strict";
var LOCK_NAME = "sync_lock";
function promiseLock(name, options, callback) {
var callback_promise = null,
controller = new AbortController();
function canceller(msg) {
controller.abort();
if (callback_promise !== null) {
callback_promise.cancel(msg);
}
}
function resolver(resolve, reject) {
if (callback === undefined) {
callback = options;
options = {};
}
options.signal = controller.signal;
function handleCallback(lock) {
if (!lock) {
// The lock was not granted - get out fast.
return reject('Lock not granted');
}
try {
callback_promise = callback();
} catch (e) {
return reject(e);
}
callback_promise = new RSVP.Queue(callback_promise)
.push(resolve, function handleCallbackError(error) {
// Prevent rejecting the lock, if the result cancelled itself
if (!(error instanceof RSVP.CancellationError)) {
canceller(error.toString());
reject(error);
}
});
return callback_promise;
}
return navigator.locks.request(name, options, handleCallback)
.then(undefined, reject);
}
return new RSVP.Promise(resolver, canceller);
}
rJS(window) rJS(window)
.ready(function (gadget) { .ready(function (gadget) {
...@@ -46,27 +95,36 @@ ...@@ -46,27 +95,36 @@
return storage.get.apply(storage, arguments); return storage.get.apply(storage, arguments);
}) })
.declareMethod('put', function () { .declareMethod('put', function () {
var storage = this.props.jio_storage; var storage = this.props.jio_storage,
return storage.put.apply(storage, arguments); argument_list = arguments;
return promiseLock(LOCK_NAME, {}, function () {
return storage.put.apply(storage, argument_list);
});
}) })
.declareMethod('remove', function () { .declareMethod('remove', function () {
var storage = this.props.jio_storage; var storage = this.props.jio_storage,
return storage.remove.apply(storage, arguments); argument_list = arguments;
return promiseLock(LOCK_NAME, {}, function () {
return storage.remove.apply(storage, argument_list);
});
}) })
.declareMethod('getAttachment', function () { .declareMethod('getAttachment', function () {
var storage = this.props.jio_storage; var storage = this.props.jio_storage;
return storage.getAttachment.apply(storage, arguments); return storage.getAttachment.apply(storage, arguments);
}) })
.declareMethod('removeAttachment', function () { .declareMethod('removeAttachment', function () {
var storage = this.props.jio_storage; var storage = this.props.jio_storage,
return storage.removeAttachment.apply(storage, arguments); argument_list = arguments;
return promiseLock(LOCK_NAME, {}, function () {
return storage.removeAttachment.apply(storage, argument_list);
});
}) })
.declareMethod('repair', function () { .declareMethod('repair', function () {
var storage = this.props.jio_storage; var storage = this.props.jio_storage,
return storage.repair.apply(storage, arguments) argument_list = arguments;
.push(undefined, function (error) { return promiseLock(LOCK_NAME, {}, function () {
throw error; return storage.repair.apply(storage, argument_list);
}); });
}); });
}(window, rJS, jIO)); }(window, rJS, jIO));
\ No newline at end of file
...@@ -76,7 +76,9 @@ ...@@ -76,7 +76,9 @@
</item> </item>
<item> <item>
<key> <string>content_type</string> </key> <key> <string>content_type</string> </key>
<value> <string>text/javascript</string> </value> <value>
<none/>
</value>
</item> </item>
<item> <item>
<key> <string>default_reference</string> </key> <key> <string>default_reference</string> </key>
...@@ -233,7 +235,7 @@ ...@@ -233,7 +235,7 @@
</item> </item>
<item> <item>
<key> <string>actor</string> </key> <key> <string>actor</string> </key>
<value> <string>zope</string> </value> <value> <unicode>zope</unicode> </value>
</item> </item>
<item> <item>
<key> <string>comment</string> </key> <key> <string>comment</string> </key>
...@@ -247,7 +249,7 @@ ...@@ -247,7 +249,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>964.14420.61705.7611</string> </value> <value> <string>1012.16567.39240.33996</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -267,7 +269,7 @@ ...@@ -267,7 +269,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1513617981.41</float> <float>1699034398.59</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -150,27 +150,14 @@ ...@@ -150,27 +150,14 @@
// There was another recent sync don't start a new sync before the time_interval! // There was another recent sync don't start a new sync before the time_interval!
return; return;
} }
return gadget.getSetting('sync_lock') return syncAllStorageWithCheck();
.push(function (sync_lock) {
if (!sync_lock) {
gadget.props.sync_locked = false;
return syncAllStorageWithCheck();
}
gadget.props.sync_locked = true;
return gadget.notifySubmitted({
message: "Auto sync is currently locked by another task " +
"and will be restarted later...",
status: "error"
});
});
}) })
.push(function () { .push(function () {
return gadget.getSetting('sync_data_interval'); return gadget.getSetting('sync_data_interval');
}) })
.push(function (timer_interval) { .push(function (timer_interval) {
if (gadget.props.offline === true || if (gadget.props.offline === true) {
gadget.props.sync_locked === true) { // Offline mode detected. Next run in 1 minute
// Offline mode detected or sync locked. Next run in 1 minute
timer_interval = 60000; timer_interval = 60000;
} else if (timer_interval === undefined) { } else if (timer_interval === undefined) {
timer_interval = gadget.props.default_sync_interval; timer_interval = gadget.props.default_sync_interval;
......
...@@ -79,7 +79,9 @@ ...@@ -79,7 +79,9 @@
</item> </item>
<item> <item>
<key> <string>content_type</string> </key> <key> <string>content_type</string> </key>
<value> <string>text/javascript</string> </value> <value>
<none/>
</value>
</item> </item>
<item> <item>
<key> <string>default_reference</string> </key> <key> <string>default_reference</string> </key>
...@@ -236,7 +238,7 @@ ...@@ -236,7 +238,7 @@
</item> </item>
<item> <item>
<key> <string>actor</string> </key> <key> <string>actor</string> </key>
<value> <string>zope</string> </value> <value> <unicode>zope</unicode> </value>
</item> </item>
<item> <item>
<key> <string>comment</string> </key> <key> <string>comment</string> </key>
...@@ -250,7 +252,7 @@ ...@@ -250,7 +252,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>964.38426.36779.39065</string> </value> <value> <string>1012.10637.27951.32512</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -270,7 +272,7 @@ ...@@ -270,7 +272,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1515058880.82</float> <float>1698678848.02</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment