I have a challenge for everyone who thinks he/she ...
# coroutines
m
I have a challenge for everyone who thinks he/she understands Kotlin Coroutines πŸ˜› I made a game with coroutines races. Have fun πŸ™‚ https://marcinmoskala.com/CoroutinesRaceGuesser/
πŸ†’ 3
❀️ 1
πŸ‘ 8
s
Nice! I especially like the focus on how coroutines and exceptions interact. I'm not sure about puzzle 10, though:
Won't the exception propagate to the scope before it reaches the
catch
block?
m
You are right, that seems incorrect to me as well, but it would be really strange as those code samples are random, and results are generated by starting actual code in runTest.
s
Oh that's interesting! I wonder if this one behaves differently in the test environment from in a real app
m
I am checking it now
s
I didn't realise the examples are random, that's really neat, especially generating the correct result automatically very nice
I didn't make it past this level btw 😞 I started to make mistakes with the delays. Should have used a pen and paper to keep track πŸ˜„. Let's see who can beat my score!
m
πŸ˜„
I need to add "High scores" functionality πŸ˜›
K 3
I can confirm your answer, now I am checking why incorrect one got generated.
s
Thanks! I'm very curious about it, I can kind of see why both answers are valid, but I'd find it hard to explain exactly why/when I would or wouldn't expect the catch block to be entered πŸ€”
I guess coroutines are kind of complicated πŸ˜„πŸ€―
m
I can see the race condition
s
I'm guessing that difference comes down to whether I'm guessing the difference must come down to which coroutine completes (fails) first, the
launch
or the
async
. If
launch
fails first, the scope is cancelled, and
await()
throws
CancellationException
. If
async
fails first,
await()
throws
Exception
(the result of the task) and skips the
catch
block. So my initial hunch where I said the exception should propagate to the scope before it reaches the catch block is actually wrong πŸ˜„
Which means I found the problem completely by accident πŸ˜‚
m
When you have an exception in async two things happen: β€’ await() throws Exception β€’ async propagates exception via scope, that gets cancelled, and the next suspension point (async()) throws CancellationException. Depending on which one is faster, a different result will be generated.
πŸ‘ 1
s
And I guess the single-threaded dispatcher used by
runTest
dispatches things in a slightly different order from
Dispatchers.Default
, hence the disparity
m
Yes, your answer might also be it, if there was (1 sec) in launch, the answer would certainly include "Got exception", so there is also this race condition πŸ™‚
πŸ‘ 1
Yes, in runTest execution depends on scheduling order, and so launch cancellation should be before we reach async(). In runBlocking launch has some exta cost so typically we should first reach calling await() πŸ™‚
That was a nice challenge πŸ™‚
Good start of a day πŸ˜‰
πŸ’― 1
image.png
πŸ’‘ 1
r
You reached level 15 on Adventure mode
πŸ˜‰ Nice work @marcinmoskala!
πŸ‘ 2
m
Is this made with Compose Wasm?
m
Yup
e
It would be nice to have an undo function πŸ™‚
m
Undo? You can clock a block to remove it
e
oh homer disappear
l
Very cool, but "Not bed" is bad ;) (typo)