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 @@
.onEvent('click', function (event) {
var gadget = this,
sync_start_time,
success = true,
element = gadget.element.querySelector("#destroyOPML");
......@@ -100,24 +99,6 @@
return gadget.notifySubmitting()
.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");
return gadget.jio_allDocs({
query: 'portal_type: "opml"',
......@@ -125,13 +106,11 @@
})
.push(function (result) {
return RSVP.all([
gadget.setSetting('sync_lock', true),
removeAllOPML(result)
]);
})
.push(function () {
return RSVP.all([
gadget.setSetting('sync_lock', false),
gadget.notifySubmitted({
message: 'All OPML removed',
status: 'success'
......@@ -139,7 +118,6 @@
]);
}, function () {
success = false;
return gadget.setSetting('sync_lock', false);
});
})
.push(function () {
......
......@@ -232,7 +232,7 @@
</item>
<item>
<key> <string>actor</string> </key>
<value> <string>zope</string> </value>
<value> <unicode>zope</unicode> </value>
</item>
<item>
<key> <string>comment</string> </key>
......@@ -246,7 +246,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>971.42397.40766.62515</string> </value>
<value> <string>1012.23628.37695.12441</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -266,7 +266,7 @@
</tuple>
<state>
<tuple>
<float>1542303383.28</float>
<float>1699538392.28</float>
<string>UTC</string>
</tuple>
</state>
......
/*global window, rJS, jIO, FormData, XMLHttpRequestProgressEvent */
/*global window, rJS, jIO, FormData, AbortController, RSVP, navigator */
/*jslint indent: 2, maxerr: 3 */
(function (window, rJS, jIO) {
"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)
.ready(function (gadget) {
......@@ -46,27 +95,36 @@
return storage.get.apply(storage, arguments);
})
.declareMethod('put', function () {
var storage = this.props.jio_storage;
return storage.put.apply(storage, arguments);
var storage = this.props.jio_storage,
argument_list = arguments;
return promiseLock(LOCK_NAME, {}, function () {
return storage.put.apply(storage, argument_list);
});
})
.declareMethod('remove', function () {
var storage = this.props.jio_storage;
return storage.remove.apply(storage, arguments);
var storage = this.props.jio_storage,
argument_list = arguments;
return promiseLock(LOCK_NAME, {}, function () {
return storage.remove.apply(storage, argument_list);
});
})
.declareMethod('getAttachment', function () {
var storage = this.props.jio_storage;
return storage.getAttachment.apply(storage, arguments);
})
.declareMethod('removeAttachment', function () {
var storage = this.props.jio_storage;
return storage.removeAttachment.apply(storage, arguments);
var storage = this.props.jio_storage,
argument_list = arguments;
return promiseLock(LOCK_NAME, {}, function () {
return storage.removeAttachment.apply(storage, argument_list);
});
})
.declareMethod('repair', function () {
var storage = this.props.jio_storage;
return storage.repair.apply(storage, arguments)
.push(undefined, function (error) {
throw error;
});
var storage = this.props.jio_storage,
argument_list = arguments;
return promiseLock(LOCK_NAME, {}, function () {
return storage.repair.apply(storage, argument_list);
});
});
}(window, rJS, jIO));
\ No newline at end of file
......@@ -76,7 +76,9 @@
</item>
<item>
<key> <string>content_type</string> </key>
<value> <string>text/javascript</string> </value>
<value>
<none/>
</value>
</item>
<item>
<key> <string>default_reference</string> </key>
......@@ -233,7 +235,7 @@
</item>
<item>
<key> <string>actor</string> </key>
<value> <string>zope</string> </value>
<value> <unicode>zope</unicode> </value>
</item>
<item>
<key> <string>comment</string> </key>
......@@ -247,7 +249,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>964.14420.61705.7611</string> </value>
<value> <string>1012.16567.39240.33996</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -267,7 +269,7 @@
</tuple>
<state>
<tuple>
<float>1513617981.41</float>
<float>1699034398.59</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -150,27 +150,14 @@
// There was another recent sync don't start a new sync before the time_interval!
return;
}
return gadget.getSetting('sync_lock')
.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"
});
});
return syncAllStorageWithCheck();
})
.push(function () {
return gadget.getSetting('sync_data_interval');
})
.push(function (timer_interval) {
if (gadget.props.offline === true ||
gadget.props.sync_locked === true) {
// Offline mode detected or sync locked. Next run in 1 minute
if (gadget.props.offline === true) {
// Offline mode detected. Next run in 1 minute
timer_interval = 60000;
} else if (timer_interval === undefined) {
timer_interval = gadget.props.default_sync_interval;
......
......@@ -79,7 +79,9 @@
</item>
<item>
<key> <string>content_type</string> </key>
<value> <string>text/javascript</string> </value>
<value>
<none/>
</value>
</item>
<item>
<key> <string>default_reference</string> </key>
......@@ -236,7 +238,7 @@
</item>
<item>
<key> <string>actor</string> </key>
<value> <string>zope</string> </value>
<value> <unicode>zope</unicode> </value>
</item>
<item>
<key> <string>comment</string> </key>
......@@ -250,7 +252,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>964.38426.36779.39065</string> </value>
<value> <string>1012.10637.27951.32512</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -270,7 +272,7 @@
</tuple>
<state>
<tuple>
<float>1515058880.82</float>
<float>1698678848.02</float>
<string>UTC</string>
</tuple>
</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