-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Offline storage plugin #1165
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Offline storage plugin #1165
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
/** | ||
* Offline Storage plugin | ||
* | ||
* Stores errors failed to get send and try to send them when | ||
* Networkf comes back or on init | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (sorry, this is a drive-by comment) is this a typo, |
||
*/ | ||
|
||
var offlineStorageKey = 'raven-js-offline-queue'; | ||
|
||
function offlineStoragePlugin(Raven, options) { | ||
options = options || {}; | ||
|
||
function processOfflineQueue() { | ||
// Let's stop here if there's no connection | ||
if (!navigator.onLine) { | ||
return; | ||
} | ||
|
||
try { | ||
// Get the queue | ||
var queue = JSON.parse(localStorage.getItem(offlineStorageKey)) || []; | ||
|
||
// Store an empty queue. If processing these one fails they get back to the queue | ||
localStorage.removeItem(offlineStorageKey); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. multiple localStorage operations are not atomic. It is possible for multiple tabs to receive this queue before the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @graingert I don't believe that library handles atomic operations between multiple browser windows. It just removes oldest item when localstorage when it's full There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here is a link to a library I created to solve this problem. There are probably other libraries out there as well. Also feel free to just copy the library code into this repo if you don't want another dependency. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Storing an entire array of the logs at once can be quite a poor usage of memory. There might be a lot of logs if a device is left offline for extended periods of time. On hybrid apps there is a very small memory limit. If there are a lot of logs or large json encoded objects, memory can spike. Possibly using indexdb or an option for a custom storage adapter would allow for more memory efficient ways of storing. |
||
|
||
queue.forEach(function processOfflinePayload(data) { | ||
// Avoid duplication verification for offline stored | ||
// as they may try multiple times to be processed | ||
Raven._lastData = null; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure if I understand your comment here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, but then when trying to send it again when get back offline, because There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Right :) |
||
|
||
// Try to process it again | ||
Raven._sendProcessedPayload(data); | ||
}); | ||
} catch (error) { | ||
Raven._logDebug('error', 'Raven transport failed to store offline: ', error); | ||
} | ||
} | ||
|
||
// Process queue on start | ||
processOfflineQueue(); | ||
|
||
// Add event listener on onravenFailure and store error on localstorage | ||
document.addEventListener('ravenFailure', function(event) { | ||
if (!event.data) { | ||
return; | ||
} | ||
|
||
try { | ||
var queue = JSON.parse(localStorage.getItem(offlineStorageKey)) || []; | ||
queue.push(event.data); | ||
localStorage.setItem(offlineStorageKey, JSON.stringify(queue)); | ||
} catch (error) { | ||
Raven._logDebug('error', 'Raven failed to store payload offline: ', error); | ||
} | ||
}); | ||
|
||
// Add event listener on online or custom event to trigger offline queue sending | ||
window.addEventListener(options.onlineEventName || 'online', processOfflineQueue); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there any alternative event that I don't know of, but could be used here? :P There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is just because the application might rely on a different event for letting other plugins know when the connection is available (e.g. on our cordova-based hybrid app we trigger a "foo-bar-online" event to the document when we're sure the app is online and it was able to make an XHR request), because "online" can easily mean "connected to the network" as in "local network" but still not be connected to the internet. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Makes perfect sense |
||
} | ||
|
||
module.exports = offlineStoragePlugin; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should
failed to get send
bethat failed to be sent
?