Skip to content

Commit

Permalink
fix deadlock for ordered ExecutionPolicy (#623)
Browse files Browse the repository at this point in the history
* add failing test

* fix deadlock for ordered ExecutionPolicy

* remove test comments
  • Loading branch information
gabrielittner authored Dec 15, 2023
1 parent 3f826ec commit 985bcd5
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ internal fun <A : Any, S : Any> Flow<A>.reduxStore(
var currentState: S = initialStateSupplier()
val getState: GetState<S> = { currentState }

val stateChanges = Channel<ChangedState<S>>()
val stateChanges = Channel<ChangedState<S>>(Channel.UNLIMITED)
val sideEffects = sideEffectBuilders.map { ManagedSideEffect(it, this@channelFlow, getState, stateChanges) }

// Emit the initial state
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,21 @@ package com.freeletics.flowredux.sideeffects

import app.cash.turbine.awaitItem
import app.cash.turbine.test
import app.cash.turbine.turbineScope
import com.freeletics.flowredux.StateMachine
import com.freeletics.flowredux.TestAction
import com.freeletics.flowredux.TestState
import com.freeletics.flowredux.dsl.ExecutionPolicy
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertIs
import kotlin.test.assertTrue
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.awaitCancellation
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.launch
import kotlinx.coroutines.test.runTest

@OptIn(ExperimentalCoroutinesApi::class)
Expand Down Expand Up @@ -74,4 +79,32 @@ internal class OnActionTest {
assertEquals(TestState.S2, awaitItem())
}
}

@Test
fun onActionOrdered() = runTest {
turbineScope {
val sm = StateMachine(TestState.GenericNullableState(null, null)) {
inState<TestState.GenericNullableState> {
on<TestAction.A1>(executionPolicy = ExecutionPolicy.ORDERED) { _, state ->
state.mutate { copy(aString = "1") }
}

on<TestAction.A2>(executionPolicy = ExecutionPolicy.ORDERED) { _, state ->
state.mutate { copy(anInt = 2) }
}
}
}

val scope = CoroutineScope(context = Dispatchers.Unconfined)
val turbine = sm.state.testIn(scope)
scope.launch {
sm.dispatch(TestAction.A2)
sm.dispatch(TestAction.A1)
}

assertEquals(TestState.GenericNullableState(null, null), turbine.awaitItem())
assertEquals(TestState.GenericNullableState("1", null), turbine.awaitItem())
assertEquals(TestState.GenericNullableState("1", 2), turbine.awaitItem())
}
}
}

0 comments on commit 985bcd5

Please sign in to comment.