KotlinBloc
KotlinBloc copied to clipboard
BLoC freezes when receiving an event that does not emit a new state
Specs
com.github.ptrbrynt.KotlinBloc:core 3.0.0 org.jetbrains.compose 1.1.0
Introduction
Hi. I'm using BLoC in my Kotlin-Compose (desktop) to manage the connection status of a peripheral device in my application.
Each screen checks the device's connection status, kept by the BLoC and requests connection if the BLoC is not in Connected state.
Since the connection is asynchronous, I have a situation where a connection event comes through and at the same time that the Connected state change occurs. In this case, the connection event received by the BLoC should be ignored.
The issue
That being said, the event handling of my BLoC is:
init {
on<HdmEvent> {event ->
when(event) {
is HdmEvent.Connect -> {
when (state) {
is HdmState.Disconnected -> {
emit(HdmState.Connecting())
}
is HdmState.Disconnecting -> {
emit(HdmState.Connecting())
}
else -> { }
}
}
...
}
If I receive a Connect event and it's in Connected state, the event should be ignored falling into the else clause, but that causes the BLoC to stop responding to any future events.
I believe if an event is received but doesn't emit a state, we reach an inconsistent state where the on function is not triggered anymore.
The "solution" I found here was to add:
else -> {
emit(state)
}
Thinking of a state machine, it kinda makes sense, because every transition (event) causes a state change, and it's an event that circulates to the state it was like in the image below

but I don't think this should trigger a state emission, because this makes the listeners of the event flow act on the state change twice, and now I have to manage the current state and the new state of the BLoC, just to avoid this issue... That should not be the listener's responsibility, since the state transition is spurious, to avoid the freezing of the BLoC.
To illustrate the freeze, I created a coroutine that sends Connect events each 200ms AFTER it's connected, and the else clause above in the BLoC is empty:

The coroutine
The states and events.
The first 2 events are received, and then, not anymore. It looks to me like erratic behaviour that should not happen.
Can you assist me in finding a better solution? Thanks