From ac5eac02c038559b3292fc17e4139a0e814c40a4 Mon Sep 17 00:00:00 2001 From: Ben Gotow Date: Thu, 13 Aug 2015 11:20:36 -0700 Subject: [PATCH] fix(sync-worker): Fix specs, add one testing backoff --- spec-nylas/nylas-sync-worker-spec.coffee | 22 +++++++++++++++++++--- src/flux/nylas-sync-worker.coffee | 9 ++++++--- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/spec-nylas/nylas-sync-worker-spec.coffee b/spec-nylas/nylas-sync-worker-spec.coffee index 6e77ea413..db3159af2 100644 --- a/spec-nylas/nylas-sync-worker-spec.coffee +++ b/spec-nylas/nylas-sync-worker-spec.coffee @@ -78,11 +78,27 @@ describe "NylasSyncWorker", -> expect(nextState[collection].fetched).toEqual(0) expect(nextState[collection].count).toEqual(0) - it "should periodically try to restart failed collection syncs", -> + it "after failures, it should attempt to resume periodically but back off as failures continue", -> + simulateNetworkFailure = => + @apiRequests[1].requestOptions.error({statusCode: 400}) + @apiRequests = [] + spyOn(@worker, 'resumeFetches').andCallThrough() @worker.start() - advanceClock(50000) - expect(@worker.resumeFetches.callCount).toBe(2) + + expect(@worker.resumeFetches.callCount).toBe(1) + simulateNetworkFailure(); expect(@worker.resumeFetches.callCount).toBe(1) + advanceClock(30000); expect(@worker.resumeFetches.callCount).toBe(2) + simulateNetworkFailure(); expect(@worker.resumeFetches.callCount).toBe(2) + advanceClock(30000); expect(@worker.resumeFetches.callCount).toBe(2) + advanceClock(30000); expect(@worker.resumeFetches.callCount).toBe(3) + simulateNetworkFailure(); expect(@worker.resumeFetches.callCount).toBe(3) + advanceClock(30000); expect(@worker.resumeFetches.callCount).toBe(3) + advanceClock(30000); expect(@worker.resumeFetches.callCount).toBe(4) + simulateNetworkFailure(); expect(@worker.resumeFetches.callCount).toBe(4) + advanceClock(30000); expect(@worker.resumeFetches.callCount).toBe(4) + advanceClock(30000); expect(@worker.resumeFetches.callCount).toBe(4) + advanceClock(30000); expect(@worker.resumeFetches.callCount).toBe(5) describe "when a count request completes", -> beforeEach -> diff --git a/src/flux/nylas-sync-worker.coffee b/src/flux/nylas-sync-worker.coffee index 797426312..0f9e53612 100644 --- a/src/flux/nylas-sync-worker.coffee +++ b/src/flux/nylas-sync-worker.coffee @@ -12,7 +12,6 @@ PAGE_SIZE = 250 class BackoffTimer constructor: (@fn) -> @reset() - @start() cancel: => clearTimeout(@_timeout) if @_timeout @@ -24,7 +23,8 @@ class BackoffTimer backoff: => @_delay = Math.min(@_delay * 1.4, 5 * 1000 * 60) # Cap at 5 minutes - console.log("Backing off after sync failure. Will retry in #{Math.floor(@_delay / 1000)} seconds.") + if not atom.inSpecMode() + console.log("Backing off after sync failure. Will retry in #{Math.floor(@_delay / 1000)} seconds.") start: => clearTimeout(@_timeout) if @_timeout @@ -46,6 +46,9 @@ class NylasSyncWorker @_terminated = false @_connection = new NylasLongConnection(api, namespace.id) + @_resumeTimer = new BackoffTimer => + # indirection needed so resumeFetches can be spied on + @resumeFetches() @_state = null DatabaseStore.findJSONObject("NylasSyncWorker:#{@_namespace.id}").then (json) => @@ -73,7 +76,7 @@ class NylasSyncWorker false start: -> - @_resumeTimer = new BackoffTimer(@resumeFetches) + @_resumeTimer.start() @_connection.start() @resumeFetches()