Skip to content

Commit bfd6a11

Browse files
authored
On update race condition (#471)
* guard updates between transition * simplify check * async as well * remove some logs * more comment removal * lint * move logic out of view * fix tests * revert typing change * remove top level reset of view transition state, leaving responsibility up to view * android check as well * cancel previous render job from android if new render job is launched * nullable job * revert core changes * no hermes * hermes only * separate default and hermes * single line
1 parent ebdcb61 commit bfd6a11

File tree

3 files changed

+11
-4
lines changed

3 files changed

+11
-4
lines changed

.circleci/config.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -293,9 +293,9 @@ jobs:
293293
command: |
294294
circle-android wait-for-boot
295295
296-
- run: |
297-
bazel test --config=ci -- //android/demo:android_instrumentation_test
298-
bazel test --config=ci --//android/player:runtime=hermes -- //android/demo:android_instrumentation_test
296+
- run: bazel test --config=ci -- //android/demo:android_instrumentation_test
297+
298+
- run: bazel test --config=ci --//android/player:runtime=hermes -- //android/demo:android_instrumentation_test
299299

300300
- run:
301301
when: always

android/player/src/main/java/com/intuit/playerui/android/ui/PlayerFragment.kt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ import com.intuit.playerui.core.managed.AsyncFlowIterator
3232
import kotlinx.coroutines.CancellationException
3333
import kotlinx.coroutines.CoroutineScope
3434
import kotlinx.coroutines.Dispatchers
35+
import kotlinx.coroutines.Job
36+
import kotlinx.coroutines.cancel
3537
import kotlinx.coroutines.flow.collectLatest
3638
import kotlinx.coroutines.flow.launchIn
3739
import kotlinx.coroutines.flow.onEach
@@ -88,6 +90,8 @@ public abstract class PlayerFragment : Fragment(), ManagedPlayerState.Listener {
8890
*/
8991
public abstract val playerViewModel: PlayerViewModel
9092

93+
private var renderingJob: Job? = null
94+
9195
init {
9296
lifecycleScope.launch {
9397
repeatOnLifecycle(State.STARTED) {
@@ -175,7 +179,8 @@ public abstract class PlayerFragment : Fragment(), ManagedPlayerState.Listener {
175179
* styles and inject that into the view tree.
176180
*/
177181
protected open fun handleAssetUpdate(asset: RenderableAsset?, animateTransition: Boolean) {
178-
lifecycleScope.launch(if (asset is SuspendableAsset<*>) Dispatchers.Default else Dispatchers.Main) {
182+
renderingJob?.cancel("handling new update")
183+
renderingJob = lifecycleScope.launch(if (asset is SuspendableAsset<*>) Dispatchers.Default else Dispatchers.Main) {
179184
whenStarted { // TODO: This'll go away when we can call a suspend version of this
180185
try {
181186
renderIntoPlayerCanvas(asset, animateTransition)

jvm/core/src/main/kotlin/com/intuit/playerui/core/view/View.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ import kotlinx.serialization.builtins.nullable
1515
public class View internal constructor(override val node: Node) : NodeWrapper {
1616
public val hooks: ViewHooks by NodeSerializableField(ViewHooks.serializer())
1717

18+
public val initialView: Asset? by NodeSerializableField(Asset.serializer().nullable)
19+
1820
public val lastUpdate: Asset? by NodeSerializableField(Asset.serializer().nullable)
1921

2022
public val resolverOptions: ResolveOptions by NodeSerializableField(ResolveOptions.serializer())

0 commit comments

Comments
 (0)