Index: chrome/browser/resources/google_now/utility.js |
diff --git a/chrome/browser/resources/google_now/utility.js b/chrome/browser/resources/google_now/utility.js |
index d0153bcc4c816bf22eccdda08914766e26d2efff..95f10612bc0c3be9aff98a000d8eb120091c8dca 100644 |
--- a/chrome/browser/resources/google_now/utility.js |
+++ b/chrome/browser/resources/google_now/utility.js |
@@ -221,3 +221,99 @@ function buildTaskManager(areConflicting) { |
wrapCallback: wrapCallback |
}; |
} |
+ |
+var storage = chrome.storage.local; |
+ |
+/** |
+ * Builds an object to manage retrying activities with exponential backoff. |
+ * @param {string} name Name of this attempt manager. |
+ * @param {function()} attempt Activity that the manager retries till it |
+ * calls 'stop' method. |
+ * @param {number} initialDelaySeconds Default first delay until first retry. |
+ * @param {number} maximumDelaySeconds Maximum delay between retries. |
+ * @return {Object} Attempt manager interface. |
+ */ |
+function buildAttemptManager( |
+ name, attempt, initialDelaySeconds, maximumDelaySeconds) { |
+ var alarmName = name + '-scheduler'; |
+ var currentDelayStorageKey = name + '-current-delay'; |
+ |
+ /** |
+ * Creates an alarm for the next attempt. The alarm is repeating for the case |
+ * when the next attempt crashes before registering next alarm. |
+ * @param {number} delaySeconds Delay until next retry. |
+ */ |
+ function createAlarm(delaySeconds) { |
+ var alarmInfo = { |
+ delayInMinutes: delaySeconds / 60, |
+ periodInMinutes: maximumDelaySeconds / 60 |
+ }; |
+ chrome.alarms.create(alarmName, alarmInfo); |
+ } |
+ |
+ /** |
+ * Schedules next attempt. |
+ * @param {number=} optionalPreviousDelaySeconds Previous delay in a sequence |
+ * of retry attemps, if specified. Not specified for scheduling first |
+ * retry in the exponential sequence. |
+ */ |
+ function scheduleNextAttempt(optionalPreviousDelaySeconds) { |
+ var base = optionalPreviousDelaySeconds ? optionalPreviousDelaySeconds * 2 : |
+ initialDelaySeconds; |
+ var newRetryDelaySeconds = |
+ Math.min(base * (1 + 0.2 * Math.random()), maximumDelaySeconds); |
+ |
+ createAlarm(newRetryDelaySeconds); |
+ |
+ var items = {}; |
+ items[currentDelayStorageKey] = newRetryDelaySeconds; |
+ storage.set(items); |
skare_
2013/05/11 00:56:23
this is just syntax but either
var items = {cDSK:
vadimt
2013/05/11 01:55:15
This would create a field 'currentDelayStorageKey'
skare_
2013/05/11 02:07:19
[ok]
oops, thought this was a literal.
Might want
|
+ } |
+ |
+ /** |
+ * Starts repeated attempts. |
+ * @param {number=} optionalFirstDelaySeconds Time until the first attempt, if |
+ * specified. Otherwise, initialDelaySeconds will be used for the first |
+ * attempt. |
+ */ |
+ function start(optionalFirstDelaySeconds) { |
skare_
2013/05/11 00:56:23
opt_FirstDelaySeconds
(s/optional/opt_ unless some
skare_
2013/05/11 01:03:05
typo -- opt_firstDelaySeconds actually.
vadimt
2013/05/11 01:55:15
Done.
|
+ if (optionalFirstDelaySeconds) { |
+ createAlarm(optionalFirstDelaySeconds); |
+ storage.remove(currentDelayStorageKey); |
+ } else { |
+ scheduleNextAttempt(); |
+ } |
+ } |
+ |
+ /** |
+ * Stops repeated attempts. |
+ */ |
+ function stop() { |
+ chrome.alarms.clear(alarmName); |
+ storage.remove(currentDelayStorageKey); |
+ } |
+ |
+ /** |
+ * Plans for the next attempt. |
+ * @param {function()} callback Completion callback. |
+ */ |
+ function planForNext(callback) { |
+ tasks.debugSetStepName('planForNext-get-storage'); |
+ storage.get(currentDelayStorageKey, function(items) { |
+ console.log('planForNext-get-storage ' + JSON.stringify(items)); |
+ scheduleNextAttempt(items[currentDelayStorageKey]); |
+ callback(); |
+ }); |
+ } |
+ |
+ chrome.alarms.onAlarm.addListener(function(alarm) { |
+ if (alarm.name == alarmName) |
+ attempt(); |
+ }); |
+ |
+ return { |
+ start: start, |
+ planForNext: planForNext, |
+ stop: stop |
+ }; |
+} |