diff --git a/background/sync-manager.js b/background/sync-manager.js index e5656df2..21a644c7 100644 --- a/background/sync-manager.js +++ b/background/sync-manager.js @@ -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 }); }