Fix ConcurrentModificationException due to FrameMetricsAggregator manipulation#2282
Fix ConcurrentModificationException due to FrameMetricsAggregator manipulation#2282markushi merged 7 commits into6.4.x-hotfixfrom
Conversation
Performance metrics 🚀
|
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| 5d9a6b1 | 372.04 ms | 429.63 ms | 57.59 ms |
| 5a92bc6 | 352.02 ms | 378.21 ms | 26.19 ms |
| efa513a | 322.63 ms | 362.73 ms | 40.10 ms |
| 222b94c | 338.71 ms | 374.32 ms | 35.61 ms |
| 9a87290 | 318.37 ms | 369.65 ms | 51.27 ms |
| f48be76 | 316.26 ms | 363.22 ms | 46.96 ms |
| 255f89e | 320.54 ms | 357.53 ms | 36.99 ms |
App size
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| 5d9a6b1 | 1.73 MiB | 2.29 MiB | 579.50 KiB |
| 5a92bc6 | 1.74 MiB | 2.33 MiB | 606.15 KiB |
| efa513a | 1.73 MiB | 2.29 MiB | 579.50 KiB |
| 222b94c | 1.74 MiB | 2.33 MiB | 606.32 KiB |
| 9a87290 | 1.73 MiB | 2.29 MiB | 579.49 KiB |
| f48be76 | 1.74 MiB | 2.33 MiB | 606.32 KiB |
| 255f89e | 1.74 MiB | 2.33 MiB | 606.32 KiB |
sentry-android-core/src/main/java/io/sentry/android/core/ActivityFramesTracker.java
Outdated
Show resolved
Hide resolved
|
|
||
| @Nullable SparseIntArray[] framesRates = null; | ||
| try { | ||
| framesRates = frameMetricsAggregator.getMetrics(); |
There was a problem hiding this comment.
This does not touch OnFrameMetricsAvailableListener.
We don't need a try/catch, if so, what is the concern?
There was a problem hiding this comment.
I agree, I still added it in order to make all frameMetricsAggregator.x calls safer. Yes, it's safe now but in theory it could change with a future update to the androidx lib. But I'm fine with removing it 👍
There was a problem hiding this comment.
Your call, upgrades to the androidx lib can cause new issues, I agree.
sentry-android-core/src/main/java/io/sentry/android/core/ActivityFramesTracker.java
Outdated
Show resolved
Hide resolved
sentry-android-core/src/main/java/io/sentry/android/core/ActivityFramesTracker.java
Outdated
Show resolved
Hide resolved
sentry-android-core/src/main/java/io/sentry/android/core/ActivityFramesTracker.java
Outdated
Show resolved
Hide resolved
sentry-android-core/src/test/java/io/sentry/android/core/ActivityFramesTrackerTest.kt
Outdated
Show resolved
Hide resolved
sentry-android-core/src/test/java/io/sentry/android/core/ActivityFramesTrackerTest.kt
Outdated
Show resolved
Hide resolved
Codecov ReportBase: 80.62% // Head: 80.62% // No change to project coverage 👍
Additional details and impacted files@@ Coverage Diff @@
## 6.4.x-hotfix #2282 +/- ##
===============================================
Coverage 80.62% 80.62%
Complexity 3368 3368
===============================================
Files 240 240
Lines 12388 12388
Branches 1646 1646
===============================================
Hits 9988 9988
Misses 1791 1791
Partials 609 609 Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. ☔ View full report at Codecov. |
|
Seeing this finally getting ready for merge, the changes are functional but definitely not very readable/maintainable. E.g. |
adinauer
left a comment
There was a problem hiding this comment.
Feel free to merge. If we can extract some of the duplicated code to make it easier to read / maintain I'd vote for that.
|
Can't approve since I created the PR |
Co-authored-by: Alexander Dinauer <adinauer@users.noreply.github.com>
|
@adinauer, is there a good reason why this PR doesn't have a description? Can we please add one? |
|
I've updated the description (copied it over from the initial PR) |
Makes sense, and I'd reuse where we already do something similar. |
Can we do that as a separate issue / PR as not to block this from being released? |
androidx.core.app.FrameMetricsAggregator is not thread safe, calling .remove() from a background thread may cause a
ConcurrentModificationException
📜 Description
Ensure calling .remove() is done on the UI thread.
💡 Motivation and Context
SentryTracer uses a
TimerandTimerTaskto finish open Transactions on a background thread. Finishing a transaction also triggers the calculation of the frame metrics as well as unregistering the activity from metric collection (FrameMetricsAggregator.remove(activity)), FrameMetricsAggregator is not thread safe, causing sporadicConcurrentModificationExceptions.💚 How did you test it?
Ensured current tests are not breaking, otherwise it's hard to test a ConcurrentModificationException.
📝 Checklist
🔮 Next steps