I'm seeing in the Arrow Fx Coroutines test suite w...
# kotest
s
I'm seeing in the Arrow Fx Coroutines test suite which uses Kotest 4.1.0, whenever a test times out. I see it with an error java.lang.InterruptedException, and all following tests in the suite fail with Timeout (which makes the suites take forever on CI too).
I noticed Kotest runs suspend functions using
runBlocking
on a
Future
scheduled on a
ExecutorService
. I'm not sure where it's going wrong. The cancellation is not correctly wired atm afaik between KotlinX & Arrow Fx, altough seeing the implementation I wasn't sure if that was necessary. Side question, would it be possible as a user to write a custom
SpecRunner
?
@sam I noticed that per test there is one call to
runBlocking
, without an argument passed for
ctx
. That means that KotlinX creates and launches an
EventLoop
on every test. Is that correct?
s
yes
s
Isn't that very straining?
s
It's tests, not production code, I tend to think keeping the codebase simpler and easier to reason about is better than trying to micro optimize
Isn't that the same argument for functional code in general 🙂
s
Not in these low level integrations 😄
Arrow Fx Coroutines internals are ugly
Well, I'm having issues with performance strain on Github Actions. That's why I ask
I'm not 100% sure about the exact perf penalties, but I'd optimise this over performance concerns. Since you're running a suspend function into a
Future
you should be able to easily remove that
runBlocking
by using an async constructor for
Future
and using
startCoroutine
instead. I could POC that if you're interested to see what it'd look like.
That comes at the cost of a single additional combinator.
s
If you can do something really simple to show me how it works then yes we can change it. I wouldn't want a PR that is really complex because I'm stupid and have to maintain it after 😂
s
lol 😂 Okay, I'll try to whip something up and create a draft PR.
👍🏻 1
s
For reference, I'm very similar with futures, not so much the kotlin coroutine internals
s
You can simply call
suspend { test() }.startCoroutine(Continuation(ctx) { /* complete async Future constructor */ })
That is functionality from the standard library to run a suspend function.
s
you must have to bind the future oncomplete into the continuation ?
s
Yes
That basically allows you to run a compiled
suspend
function in a
Future
runtime without using KotlinX.
So you only pay the cost of the
Future
and nothing else.
s
So it's not doing any of the coroutine dispatcher stuff
It's just running your future in whatever context your future normally runs in, and suspends waiting on that
s
Yes
So it's not doing any of the coroutine dispatcher stuff
You're suspend functions can still be using these KotlinX dispatchers in user land if they want
s
I quite like that
s
Yes, that should be a quite small change. Right?
s
I think so yes