https://kotlinlang.org logo
#orbit-mvi
Title
# orbit-mvi
o

Oleksii Malovanyi

04/29/2021, 1:00 PM
Hey guys, hi! I wonder, how do you handle infinite flow subscriptions? Currently, the only way works for me is
Copy code
flow<Unit> {
            while (true) {
                delay(3000)
                emit(Unit)
            }
        }.flowOn(<http://Dispatchers.IO|Dispatchers.IO>).onEach { _ ->
            intent { reduce { it } }
        }.launchIn(viewModelScope)
Unfortunately
intent
coroutine couldn’t be used for this, as it would block all new messages from the RealContainer’s channel
Copy code
intent {
            flow<Unit> {
                while (true) {
                    delay(3000)
                    emit(Unit)
                }
            }.flowOn(<http://Dispatchers.IO|Dispatchers.IO>).onEach { _ ->
                intent { reduce { it } }
            }.collect()
        }
1
m

Mikolaj Leszczynski

04/29/2021, 1:49 PM
I thought we had a test or recommendation for this but for the life of me I can’t find it. I think we need to update our docs. I think we tested it with something to this extent:
Copy code
intent {
                withContext(<http://Dispatchers.IO|Dispatchers.IO>) {
                    flow<Unit> {
                        while (true) {
                            delay(3000)
                            emit(Unit)
                        }
                    }.collect {
                        reduce { it }
                    }
                }
            }
let me know whether this works or not - it should in theory but it’s not well tested enough AFAICS
you don’t really need to wrap
reduce
in
intent
I don’t think
changing the context should help unblock the orbit event loop (I’m not sure how that relates to
flowOn
. Mainly you need to make sure that you’re collecting the flow on another dispatcher
If that still doesn’t look like it works, please file a bug report and we’ll look into it
looks like we even have a ticket for it https://github.com/orbit-mvi/orbit-mvi/issues/15
o

Oleksii Malovanyi

04/29/2021, 5:19 PM
@Mikolaj Leszczynski nah, it still won’t work as the parent coroutine from the
RealContainer
still waits for
collect
to finish (and it never finishes). I’ve tried to modify
RealContainer
to receive channel’s messages as a flow in a separate coroutine, but the problem is
reduce
state is in a race condition then 😞 I’ll try to play around it a bit and propose to move our conversation to github’s issue 🔝
👍 1
m

Mikolaj Leszczynski

04/29/2021, 5:39 PM
Odd, I need to run some tests too
Just to rule things out, are you observing this behaviour in production code or tests
o

Oleksii Malovanyi

04/29/2021, 5:53 PM
prod
I’ll upload test branch with a possible way to fix in 5 mins
m

Mikolaj Leszczynski

04/29/2021, 6:16 PM
Thanks I'll take a look.
Today
😱 1
This is an important issue 😉
o

Oleksii Malovanyi

04/29/2021, 6:34 PM
btw, as a concept I thought about two more variants: 1. add another dsl method for infinite loops; 2. provide (child) scope as a part of simple context (e.g. for
launchIn
) to not to block the
intent
with
collect
But surely wouldn’t go with either if we still could make
intent
work safely without blocking
m

Mikolaj Leszczynski

04/29/2021, 6:35 PM
Yeah that's what I'm going to try to figure out.
1
I apologize, we should have tested this better
But I think this feature got lost somewhere when we transitioned from the strict to the simple syntax
o

Oleksii Malovanyi

04/29/2021, 6:37 PM
while your lib is free you should apologise for nothing 😂 still grateful for your efforts
m

Mikolaj Leszczynski

04/29/2021, 6:40 PM
I expect better from myself 😜
Life's been getting in the way of improving this lib though
@Oleksii Malovanyi I’ve figured it out. So the reason it doesn’t work (and why I could have sworn it worked earlier 🤪) is that we broke it when introducing the exception handler change. Specifically, the supervisorScope will wait until the coroutines inside it are finished. This means it will indeed block forever when we collect an infinite flow. The bug eluded us because it worked when an exception handler was not installed (which is the case for the majority of tests), so unit tests didn’t pick it up. I’ve replaced the supervisor scope with a job instead, PR ready here: https://github.com/orbit-mvi/orbit-mvi/pull/44
I’ll release a hotfix as soon as this is in
o

Oleksii Malovanyi

04/30/2021, 6:03 AM
@Mikolaj Leszczynski wow! Also the corresponding code looks now much smoother metal I feel a bit bad for introducing the issue, but I also feel thankful for such a quick fix from your side, Thanks!
m

Mikolaj Leszczynski

04/30/2021, 6:41 AM
Relax, it did go through a code review and we haven't noticed!
❤️ 1
Code doesn't break only if you never add any new features 😜
Besides it was only confined to people having an exception handler installed, I think we caught it early enough that most people don't have one
2
m

miqbaldc

04/30/2021, 7:48 AM
thanks #orbit-mvi team & @Oleksii Malovanyi for the report! ❤️
m

Mikolaj Leszczynski

04/30/2021, 8:13 AM
there was some sort of hiccup in the maven central upload process, but we will finalise the release today for sure
19 Views