Fixed
Status Update
Comments
ng...@google.com <ng...@google.com>
ap...@google.com <ap...@google.com> #2
Yigit, do you have time to fix it?
reemission of the same liveData is racy
reemission of the same liveData is racy
ma...@google.com <ma...@google.com> #3
yea i'll take it.
ra...@google.com <ra...@google.com> #4
Thanks for the detailed analysis. This may not be an issue anymore since we've started using Main.immediate there but I' not sure; I'll try to create a test case.
cc...@google.com <cc...@google.com> #5
just emitting same live data reproduces the issue.
@Test
fun raceTest() {
val subLiveData = MutableLiveData(1)
val subject = liveData(testScope.coroutineContext) {
emitSource(subLiveData)
emitSource(subLiveData) //crashes
}
subject.addObserver().apply {
testScope.advanceUntilIdle()
}
}
@Test
fun raceTest() {
val subLiveData = MutableLiveData(1)
val subject = liveData(testScope.coroutineContext) {
emitSource(subLiveData)
emitSource(subLiveData) //crashes
}
subject.addObserver().apply {
testScope.advanceUntilIdle()
}
}
cc...@google.com <cc...@google.com> #6
With 2.2.0-alpha04 (that use Main.immediate), the issue seems to be still there (I tested it by calling emitSource() twice, like your test case)
cc...@google.com <cc...@google.com> #7
yea sorry immediate does not fix it.
I actually have a WIP fix for it:
https://android-review.googlesource.com/c/platform/frameworks/support/+/1112186
if your case is the one i found (emitting same LiveData multiple times, as shown in #5) you can work around it by adding a dummy transformation.
val subLiveData = MutableLiveData(1)
val subject = liveData(testScope.coroutineContext) {
emitSource(subLiveData.map {it })
emitSource(subLiveData.map {it} )
}
I actually have a WIP fix for it:
if your case is the one i found (emitting same LiveData multiple times, as shown in #5) you can work around it by adding a dummy transformation.
val subLiveData = MutableLiveData(1)
val subject = liveData(testScope.coroutineContext) {
emitSource(subLiveData.map {it })
emitSource(subLiveData.map {it} )
}
cc...@google.com <cc...@google.com> #8
Project: platform/frameworks/support
Branch: androidx-master-dev
commit af12e75e6b4110f48e44ca121466943909de8f06
Author: Yigit Boyar <yboyar@google.com>
Date: Tue Sep 03 12:58:11 2019
Fix coroutine livedata race condition
This CL fixes a bug in liveData builder where emitting same
LiveData source twice would make it crash because the second
emission registry could possibly happen before first one is
removed as source.
We fix it by using a suspending dispose function. It does feel
a bit hacky but we cannot make DisposableHandle.dispose async
and we do not want to block there. This does not mean that there
is a problem if developer disposes it manually since our emit
functions take care of making sure it disposes (and there is
no other way to add source to the underlying MediatorLiveData)
Bug: 140249349
Test: BuildLiveDataTest#raceTest_*
Change-Id: I0b464c242a583da4669af195cf2504e2adc4de40
M lifecycle/lifecycle-livedata-ktx/api/2.2.0-alpha05.txt
M lifecycle/lifecycle-livedata-ktx/api/current.txt
M lifecycle/lifecycle-livedata-ktx/api/public_plus_experimental_2.2.0-alpha05.txt
M lifecycle/lifecycle-livedata-ktx/api/public_plus_experimental_current.txt
M lifecycle/lifecycle-livedata-ktx/api/restricted_2.2.0-alpha05.txt
M lifecycle/lifecycle-livedata-ktx/api/restricted_current.txt
M lifecycle/lifecycle-livedata-ktx/src/main/java/androidx/lifecycle/CoroutineLiveData.kt
M lifecycle/lifecycle-livedata-ktx/src/test/java/androidx/lifecycle/BuildLiveDataTest.kt
https://android-review.googlesource.com/1112186
https://goto.google.com/android-sha1/af12e75e6b4110f48e44ca121466943909de8f06
Branch: androidx-master-dev
commit af12e75e6b4110f48e44ca121466943909de8f06
Author: Yigit Boyar <yboyar@google.com>
Date: Tue Sep 03 12:58:11 2019
Fix coroutine livedata race condition
This CL fixes a bug in liveData builder where emitting same
LiveData source twice would make it crash because the second
emission registry could possibly happen before first one is
removed as source.
We fix it by using a suspending dispose function. It does feel
a bit hacky but we cannot make DisposableHandle.dispose async
and we do not want to block there. This does not mean that there
is a problem if developer disposes it manually since our emit
functions take care of making sure it disposes (and there is
no other way to add source to the underlying MediatorLiveData)
Bug: 140249349
Test: BuildLiveDataTest#raceTest_*
Change-Id: I0b464c242a583da4669af195cf2504e2adc4de40
M lifecycle/lifecycle-livedata-ktx/api/2.2.0-alpha05.txt
M lifecycle/lifecycle-livedata-ktx/api/current.txt
M lifecycle/lifecycle-livedata-ktx/api/public_plus_experimental_2.2.0-alpha05.txt
M lifecycle/lifecycle-livedata-ktx/api/public_plus_experimental_current.txt
M lifecycle/lifecycle-livedata-ktx/api/restricted_2.2.0-alpha05.txt
M lifecycle/lifecycle-livedata-ktx/api/restricted_current.txt
M lifecycle/lifecycle-livedata-ktx/src/main/java/androidx/lifecycle/CoroutineLiveData.kt
M lifecycle/lifecycle-livedata-ktx/src/test/java/androidx/lifecycle/BuildLiveDataTest.kt
sh...@gmail.com <sh...@gmail.com> #9
In the latest stable version of the library (compared to beta verison), it looks we are reinstalling the apk during each iteration, which is clearing application data for each macrobenchmark. Issue with that approach is, when measuring the performance (esp. FrameTimingMetric) for screens deep inside, the onboarding flow of the app needs to be repeated every time which is not ideal. We just want to measure the performance improvements for users who are updating to the latest versions. Can we not just clear the clear ART profiles between runs. Can you please advice how this can be achieved. Do let me know if you need more details on this issue.
ra...@google.com <ra...@google.com> #10
Unfortunately it's not possible to just clear ART profiles prior to Android T on user builds. This is why we need to re-install the APK.
On the next iteration of Macrobenchmark (1.2.0-alpha01), we will try and clear profile caches if the session is rooted.
sh...@gmail.com <sh...@gmail.com> #11
Thanks for the quick and prompt response. Sorry which version of android are you referring here when you say Android T
be...@google.com <be...@google.com> #12
Android T is the development name for Android 13.
th...@gmail.com <th...@gmail.com> #13
Hi, coming from the android docs here (https://developer.android.com/topic/performance/baselineprofiles/overview ) and just wanted to be clear on a point.
"Resetting ART profile caches isn't allowed on user (non-rooted) builds. To work around this, androidx.benchmark:benchmark-macro-junit4:1.1.0 includes a fix that reinstalls the app during the benchmark (issue)."
When the docs say a "fix that reinstalls the app during the benchmark", and in the above comment, where you talk about 'clearing application data for each macrobenchmark', I just wanted to be clear this relates to running benchmarks only. It does not mean that when we upload our baseline profile with our APK version for the first time, our users will lose their application data? I'm new to this area of development so thanks for patience with the potentially rudimentary enquiry...!
"Resetting ART profile caches isn't allowed on user (non-rooted) builds. To work around this, androidx.benchmark:benchmark-macro-junit4:1.1.0 includes a fix that reinstalls the app during the benchmark (issue)."
When the docs say a "fix that reinstalls the app during the benchmark", and in the above comment, where you talk about 'clearing application data for each macrobenchmark', I just wanted to be clear this relates to running benchmarks only. It does not mean that when we upload our baseline profile with our APK version for the first time, our users will lose their application data? I'm new to this area of development so thanks for patience with the potentially rudimentary enquiry...!
ml...@google.com <ml...@google.com> #14
The app data is cleared only when running the Macrobenchmark locally on the device as part of the verification/generation process. No action is done to either the published app, or to apps on other devices.
When you upload the baseline profile with the APK/AAB, it's already in the generated (binary) form and it won't clear any user data.
Description
Macrobenchmarks needs to clear ART profiles between runs to ensure a clean slate before a measurement.
However, calling
cmd package compile --reset
is not supported on user builds at all. This means, that we can't actually rely on--reset
.Additional context: b/230518212