-
-
Notifications
You must be signed in to change notification settings - Fork 451
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
Reduce excessive CPU usage when serializing breadcrumbs to disk #4181
Conversation
Performance metrics 🚀
|
Revision | Plain | With Sentry | Diff |
---|---|---|---|
473dcc6 | 406.02 ms | 455.16 ms | 49.14 ms |
d877760 | 672.94 ms | 788.46 ms | 115.52 ms |
ca480b4 | 389.82 ms | 456.52 ms | 66.70 ms |
247dd70 | 396.72 ms | 419.14 ms | 22.42 ms |
App size
Revision | Plain | With Sentry | Diff |
---|---|---|---|
473dcc6 | 1.58 MiB | 2.21 MiB | 645.19 KiB |
d877760 | 1.58 MiB | 2.21 MiB | 646.64 KiB |
ca480b4 | 1.58 MiB | 2.21 MiB | 645.20 KiB |
247dd70 | 1.58 MiB | 2.21 MiB | 646.61 KiB |
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.
Just a question regarding setBreadcrumbs()
, but it's good
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.
Looks good to me! Do I assume right that if someone upgrades the SDK, and the devices has pending ANRs, they won't be enriched, as the scope data is only available in the old format?
if (breadcrumbs == null) { | ||
return; | ||
} | ||
if (event.getBreadcrumbs() == null) { | ||
event.setBreadcrumbs(new ArrayList<>(breadcrumbs)); | ||
event.setBreadcrumbs(breadcrumbs); |
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.
Well spotted, nice!
Yes that's right (only breadcrumbs would be missing though)! But I guess it's fine to accept that trade-off (and it's probably not going to be a very common scenario to have an ANR in-between app updates). Left a comment also: try {
queueFile = new QueueFile.Builder(file).size(options.getMaxBreadcrumbs()).build();
} catch (IOException e) {
// if file is corrupted we simply delete it and try to create it again. We accept
// the trade
// off of losing breadcrumbs for ANRs that happened right before the app has
// received an
// update where the new format was introduced
file.delete();
queueFile = new QueueFile.Builder(file).size(options.getMaxBreadcrumbs()).build();
} |
* WIP * WIP * Remove redundant line * Add Tests * api dump * Formatting * REset scope cache on new init * Clean up * Comment * Changelog * Workaround square/tape#173 * Add a comment to setBreadcrumbs * Address PR review * Update CHANGELOG.md
… (#4260) * WIP * WIP * Remove redundant line * Add Tests * api dump * Formatting * REset scope cache on new init * Clean up * Comment * Changelog * Workaround square/tape#173 * Add a comment to setBreadcrumbs * Address PR review * Update CHANGELOG.md
📜 Description
QueueFile
(vendored from https://github.com/square/tape) which allows us to write breadcrumbs atomically one-by-one using RandomAccessFile under the hoodmaxElements
and works as a ring buffer based on the number of elements in the queueresetCache
method that cleans up the disk cache on every init (but after the ANR processing is done) to ensure clean state and that we don't enrich with outdated scope valuesBefore
After
Also posting a perfetto trace query where we have ~50
addBreadcrumb
calls to confirm that time spent inaddBreadcrumb
does not increase with the number of breadcrumbs added:💡 Motivation and Context
Closes #3168
💚 How did you test it?
manually + automated
📝 Checklist
sendDefaultPII
is enabled.🔮 Next steps
Another potential improvement could be to batch breadcrumbs in-memory first, before writing to disk, and then flush every 1-2 seconds as batches to reduce I/O even further. The trade-off would be that we can lose some important breadcrumbs if an error occurs right within that timeframe. For now I would still like to keep it as-is, but if we receive further reports about excessive I/O we can implement that improvement too. I'm leaving the code snippet here so we can come back to it later and just copy-paste it:
Code snippet for batched writes
as a result we just had 2 I/O writes:
