randomize sync interval to avoid infinite deadlocks (#1250)

* randomize sync interval to avoid infinite deadlocks

* autoretry with a randomly increasing delay
This commit is contained in:
tophf 2021-07-07 00:19:18 +03:00 committed by GitHub
parent 264544dfa9
commit 44b08dc089
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -11,6 +11,7 @@ const syncMan = (() => {
const SYNC_DELAY = 1; // minutes
const SYNC_INTERVAL = 30; // minutes
const SYNC_LOCK_RETRIES = 10; // number of retries before the error is reported for scheduled sync
const STATES = Object.freeze({
connected: 'connected',
connecting: 'connecting',
@ -26,6 +27,7 @@ const syncMan = (() => {
currentDriveName: null,
errorMessage: null,
login: false,
lockRetries: 0,
};
let lastError = null;
let ctrl;
@ -40,9 +42,11 @@ const syncMan = (() => {
{runNow: true});
});
chrome.alarms.onAlarm.addListener(info => {
if (info.name === 'syncNow') {
syncMan.syncNow();
chrome.alarms.onAlarm.addListener(async ({name}) => {
if (name === 'syncNow') {
await syncMan.syncNow({isScheduled: true});
const retrying = status.lockRetries / SYNC_LOCK_RETRIES * Math.random();
schedule(SYNC_DELAY + SYNC_INTERVAL * (retrying || 1));
}
});
@ -139,7 +143,7 @@ const syncMan = (() => {
emitStatusChange();
},
async syncNow() {
async syncNow({isScheduled} = {}) {
if (ready.then) await ready;
if (!currentDrive || !status.login) {
console.warn('cannot sync when disconnected');
@ -152,11 +156,16 @@ const syncMan = (() => {
} catch (err) {
status.errorMessage = err.message;
lastError = err;
if (isScheduled &&
err.code === 409 &&
++status.lockRetries <= SYNC_LOCK_RETRIES) {
return;
}
if (isGrantError(err)) {
status.login = false;
}
}
status.lockRetries = 0;
emitStatusChange();
},
};
@ -247,8 +256,7 @@ const syncMan = (() => {
function schedule(delay = SYNC_DELAY) {
chrome.alarms.create('syncNow', {
delayInMinutes: delay,
periodInMinutes: SYNC_INTERVAL,
delayInMinutes: delay, // fractional values are supported
});
}