Status Update
Comments
ru...@gmail.com <ru...@gmail.com> #2
I suspect this change is the culprit.
ra...@google.com <ra...@google.com> #3
Bug reproducible in compose NavHost when compose sets same graph consecutively.
Upon setting same graph the second time, the original _graph
nodes were not properly replaced by the new graph
node instances. When navigating to new destination in addEntryToBackstack
:
findDestination(destination.id)
was not able to find destination node (a new instance) amongst the old nodes (old instances). Therefore it proceeds to re-add new node's hierarchy resulting in duplicated root node.
The fix to
ru...@gmail.com <ru...@gmail.com> #4
Branch: androidx-main
commit 5499d88b63726e63900b89d3100be1b3a17b84ce
Author: Clara Fok <clarafok@google.com>
Date: Tue Mar 28 17:00:19 2023
Fix set same graph to replace old destinations
When setting the same graph (exact same routes and destinations but different instances), NavController would keep the original graph but replace the existing graph's nodes with the new graph's nodes. Fix the replace logic to ensure this replacement happens. Also replace backqueue's entry destinations with new instances to ensure the graph and backstack is in sync.
Test: ./gradlew navigation:navigation-compose:cC
Bug: 275258161
Bug: 275407804
Relnote: "When NavController sets the same graph with same route and destinations, it now properly replaces its current graph nodes and its bacstack destinations with new instances."
Change-Id: I5bc582e315578ee53383596070ee3ea4a23aed69
M navigation/navigation-compose/build.gradle
M navigation/navigation-compose/src/androidTest/java/androidx/navigation/compose/NavHostTest.kt
M navigation/navigation-runtime/src/main/java/androidx/navigation/NavController.kt
ru...@gmail.com <ru...@gmail.com> #5
Fixed internally and will be available navigation 2.6.0-alpha09
su...@google.com <su...@google.com> #6
The following release(s) address this bug.It is possible this bug has only been partially addressed:
androidx.navigation:navigation-compose:2.6.0-alpha09
androidx.navigation:navigation-runtime:2.6.0-alpha09
ru...@gmail.com <ru...@gmail.com> #7
It looks good to me. At least, this specific behaviour seems to be fixed.
ru...@gmail.com <ru...@gmail.com> #8
ra...@google.com <ra...@google.com> #9
The behavior is actually consistent. Once your worker starts running, if we get a call to enqueueUniquePeriodicWork a new work request and with ExistingPeriodicWorkPolicy.REPLACE we will stop existing work.
If your Worker was not running, then there is nothing to cancel. This is just a matter of timing.
ru...@gmail.com <ru...@gmail.com> #10
ra...@google.com <ra...@google.com> #11
ra...@google.com <ra...@google.com> #12
ru...@gmail.com <ru...@gmail.com> #13
ra...@google.com <ra...@google.com> #14
So essentially, your worker starts, and mid-way the constraints are unmet. At this point because your Worker may not recover gracefully, we cancel and reschedule work. This happens for all your workers actually (if you turn on verbose logging you can see that).
This too is expected.
to...@gmail.com <to...@gmail.com> #15
su...@google.com <su...@google.com> #16
#15: File a separate bug, with sample code or a sample app. The issue is vague enough that there could be something completely different happening.
ru...@gmail.com <ru...@gmail.com> #17
ra...@google.com <ra...@google.com>
to...@gmail.com <to...@gmail.com> #18
java.util.concurrent.CancellationException: Task was cancelled.
at androidx.work.impl.utils.futures.AbstractFuture.cancellationExceptionWithCause(AbstractFuture.java:1184)
at androidx.work.impl.utils.futures.AbstractFuture.getDoneValue(AbstractFuture.java:514)
at androidx.work.impl.utils.futures.AbstractFuture.get(AbstractFuture.java:475)
at androidx.work.impl.WorkerWrapper$2.run(WorkerWrapper.java:245)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:841)
In our case:
fun scheduleHighlightsSync() {
val request = PeriodicWorkRequest.Builder(SyncHighlightsWorker::class.java, 1, TimeUnit.HOURS)
.setConstraints(Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.setRequiresBatteryNotLow(true)
.build())
.build()
WorkManager.getInstance().enqueueUniquePeriodicWork(SYNC_HIGHLIGHTS,
ExistingPeriodicWorkPolicy.KEEP, request)
}
according to the logs TimeUnit.HOURS is ignored and we get them several times per second on SDK < 23
ru...@gmail.com <ru...@gmail.com> #19
01-09 18:36:22.450 12508-12529/com.github.rubensousa.workkitkatbug D/TestWorkerB: I did some work
01-09 18:36:22.740 12508-12528/com.github.rubensousa.workkitkatbug D/TestWorkerC: I did some work
01-09 18:36:22.750 12508-12529/com.github.rubensousa.workkitkatbug D/TestWorkerD: I did some work
01-09 18:36:23.050 12508-12528/com.github.rubensousa.workkitkatbug D/TestWorkerE: I did some work
01-09 18:36:52.350 12508-12529/com.github.rubensousa.workkitkatbug D/TestWorkerA: I did some work
01-09 18:36:52.360 12508-12528/com.github.rubensousa.workkitkatbug D/TestWorkerB: I did some work
01-09 18:36:52.650 12508-12529/com.github.rubensousa.workkitkatbug D/TestWorkerC: I did some work
01-09 18:36:52.650 12508-12528/com.github.rubensousa.workkitkatbug D/TestWorkerD: I did some work
01-09 18:36:52.950 12508-12529/com.github.rubensousa.workkitkatbug D/TestWorkerE: I did some work
01-09 18:37:22.350 12508-12528/com.github.rubensousa.workkitkatbug D/TestWorkerA: I did some work
01-09 18:37:22.380 12508-12529/com.github.rubensousa.workkitkatbug D/TestWorkerB: I did some work
01-09 18:37:22.660 12508-12528/com.github.rubensousa.workkitkatbug D/TestWorkerC: I did some work
01-09 18:37:22.680 12508-12529/com.github.rubensousa.workkitkatbug D/TestWorkerD: I did some work
01-09 18:37:22.960 12508-12528/com.github.rubensousa.workkitkatbug D/TestWorkerE: I did some work
01-09 18:38:22.350 12508-12529/com.github.rubensousa.workkitkatbug D/TestWorkerA: I did some work
01-09 18:38:22.390 12508-12528/com.github.rubensousa.workkitkatbug D/TestWorkerB: I did some work
01-09 18:38:22.660 12508-12529/com.github.rubensousa.workkitkatbug D/TestWorkerC: I did some work
01-09 18:38:22.690 12508-12528/com.github.rubensousa.workkitkatbug D/TestWorkerD: I did some work
01-09 18:38:22.950 12508-12529/com.github.rubensousa.workkitkatbug D/TestWorkerE: I did some work
Logs when all workers are affected. Even though Result.sucess() was returned, due to this issue, WorkManager keeps retrying them. You can see the exponential backoff starting at 30 sec and going to 1 min, 2 min, 4 min etc
Description
Version used: 1.0.0-beta1
Devices/Android versions reproduced on: API 19
This seems to be happening on API 19 only.
To reproduce, just add a Thread.sleep(1000) in any worker before returning Result.SUCCESS. Worker is stopped due to cancellation instead of being treated as being successful. This causes the worker to being retried.
In our case, the behavior is the same. We're using RxJava and blocking observable operators to perform network requests. This issue causes API 19 devices to keep running the same worker using the backoff strategy instead of marking it as success.
Sample project: