https://kotlinlang.org logo
#coroutines
Title
# coroutines
d

dave08

10/22/2018, 10:21 AM
Why does this test fail?
Copy code
val progress = Channel<Long>(Channel.CONFLATED)
			val progressList = GlobalScope.async { progress.toList() }

			runBlocking {
				val progressResult = (0L..20L step 2).onEach { progress.offer(it) }
				progress.close()

				assertThat(progressResult.toList()).toBe(progressList.await())
			}
progressList
is []...
g

gildor

10/22/2018, 10:26 AM
not enough time to dispatch those updates. You use offer which doesn’t suspend
d

dave08

10/22/2018, 10:27 AM
send also doesn't work 🤕
g

gildor

10/22/2018, 10:29 AM
because also not dispatched probably
d

dave08

10/22/2018, 10:30 AM
?
I see that when I put a
delay(20)
the test passes with send...
I just don't understand why,
send
should have suspended like you said?
g

gildor

10/22/2018, 10:38 AM
Because this is how conflaited channel works
Never suspend
d

dave08

10/22/2018, 10:41 AM
Thanks, that's much clearer! So in a real download, it would work since there is some time while reporting download progress, or will
toList()
return immediately while progress is still being sent..? I don't necessarily suspend while receiving bytes...
g

gildor

10/22/2018, 11:31 AM
But why you need this for progress?
If progress is so fast and channel even never dispatched why it's so important to have all events
Use non-conflated channels if you want to have all events and warranty of delivery
d

dave08

10/22/2018, 11:34 AM
It's not that fast, I'm just unit testing, so I have a mock server... I just wanted to make sure that I'm getting some progress, I just didn't get any...
g

gildor

10/22/2018, 11:37 AM
You run it in runBlocking and do not give dispatcher chance to dispatch any other coroutine between offer calls
Try to add yeld after each progress call, it at least allow to run any other coroutines, so may be solve your problem with unit test
d

dave08

10/22/2018, 11:39 AM
yield still doesn't work... only delay(1) or Thread.sleep(20), Thread.sleep(10) sometimes works, sometimes doesn't 🙃 I need at least the last part to be able to sum up the total bytes downloaded... but you're saying that in that case I'll be getting it since it's not going to go so fast...
But the async is running on GlobalScope, which is Default dispatcher... so why shouldn't it run (even in runBlocking... GlobalScope doesn't inherit from it...)?
g

gildor

10/22/2018, 12:27 PM
If you want overall amount of bytes, just return it as result of suspend function
Do not use conflate channel to deliver critical result
Yes, you right about global scope didn't notice that
3 Views