Created
March 27, 2016 23:46
-
-
Save ryanabel03/ead76192df9b670a14f5 to your computer and use it in GitHub Desktop.
Ember.js Network Request Retries
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ApplicationAdpater = DS.ActiveModelAdapter.extend | |
synchronizer: Em.inject.service() | |
ajax: (url, type, options) -> | |
hash = @ajaxOptions(url, type, options) | |
# set up hash.success & hash.error callbacks normally | |
@get('synchronizer').handleRequest(hash) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
afterModel: (resolvedModel) -> | |
# Load from local storage | |
@get('synchronizer.syncQueue').loadStateFromPersistentStorage(user.get('id')).then (entries) -> | |
if entries.length > 0 | |
# Re-populate queue | |
@get('synchronizer.syncQueue').replaceWithEntries(entries) | |
# start syncing | |
@get('synchronizer').startSync() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
StorageService = Em.Object.extend | |
init: -> | |
@set 'maxOrder', 0 | |
@set 'localForage', localforage | |
@populateMaxOrder() | |
# The request order is determined by what already exists in local storage | |
populateMaxOrder: -> | |
new Em.RSVP.Promise (resolve, reject) => | |
@get('localForage').iterate (value, key, index) => | |
if @get('maxOrder') < value.order | |
@set 'maxOrder', value.order | |
return | |
modelJson = @get('syncModelRepository').jsonForModel entry.get('model') | |
serialized = { | |
id: @idForEntry(entry) # Generate UUID to identify entry | |
order: @get('maxOrder') + 1 | |
queueEntry: @get('syncQueueEntryRepository').jsonForEntry(entry) # Serialize entry for storage | |
model: modelJson | |
} | |
new Em.RSVP.Promise(resolve, reject) => | |
@get('localforage').setItem(@idForEntry(entry), serialized).then (value) => | |
resolve(value) | |
, (err) => | |
reject(err) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
SyncQueue = Em.Object.extend | |
init: -> | |
@set 'queue', [] | |
pushEntry: (entry) -> | |
@get('queue').pushObject(entry) | |
@get('storageService').pushEntry(entry) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Synchronizer = Em.Object.extend | |
handleRequest: (opts) -> | |
# Create an object that describes the request | |
@get('syncQueueEntryRepository').entryForJqueryOpts(opts).then (entry) => | |
# Push that object into local storage | |
@get('syncQueue').pushEntry(entry).finally => | |
# Tell the application that the request was successful | |
opts.success({}, "success", entry) | |
processRequests: -> | |
entry = @get('syncQueue.firstObject') | |
if entry? | |
# deserialize entry into request | |
opts = @get('syncQueueEntryRepository').jqueryOptsForEntry(entry) | |
# Make the request | |
Ember.$.ajax(opts).then (result) => | |
# Success case | |
Em.run => | |
# Request was successful, so remove that entry | |
@get('syncQueue').removeEntry(entry).then (val) => | |
# Push resulting objects into the Store | |
@handleResponse(result, entry) | |
# Process the next request | |
Em.run.once @, 'processRequest' | |
, if ((not jqXHR.readyState?) or jqXHR.readyState == 0) | |
# Connectivity problem -- keep retrying | |
Em.run => | |
# Update a retry timer | |
@_backoffRetrySyncTime() | |
# Re-run the request after the backoff has ended | |
Ember.run.later @, 'processRequest', @get('retrySyncInSeconds') * 1000 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment