Hello :slightly_smiling_face: I am trying to under...
# arrow
a
Hello 🙂 I am trying to understand a bit how to use
either
with coroutines in Springboot and I am not sure I fully understand what’s happening. Take for example this code:
Copy code
suspend myServiceFunction() = either {
  val r1 = someApiCall(...).bind() 
    // Either<Fail,Res1>
  val r2 = someOtherApiCall(...).bind()
    // Either<Fail,Res2>

  combineOperation(r1, r2) // Either<Fail, Res2>
}
My question is the following: how can we best make
someApiCall
and
someOtherApiCall
run in parallel? Is the
bind
for obtaining
r2
is waiting for
r1
to first get returned? Thanks 🙂
* given
someApiCall
and
someOtherApiCall
are using async rest clients
s
Hey @Andrei Bechet, This is running in sequence as the code suggest. There is no magic going on anywhere.
Is the 
bind
 for obtaining 
r2
 is waiting for 
r1
 to first get returned?
So the answer to this question is yes. So
bind
unwraps
Either.Right
, and if it find
Either.Left
it jumps out of the
either { }
block and returns the encountered
Either.Left
value. This allows you write imperative style code, instead of
flatMap
based code. This snippet is equivalent to your code:
Copy code
someApiCall(...).flatMap { r1 ->
  someOtherApiCall(...).flatMap { r2 ->
    combineOperation(r1, r2)
  }
}
If
combineOperation
is also returning
Either
at least, and if so then your snippet is probably missing a
bind()
on
combineOperation(r1, r2)
.
🙏 1
👍 1
a
Thanks for the very fast reply 🙂 How would you go about running
someApiCall
and
someOtherApiCall
in simultaneously and doing the
bing
only after they’re done?
👍 1
s
So to answer your question, how can you make this run in parallel. You just want to use
parZip
from Arrow Fx Coroutines, which allows for doing this:
Copy code
suspend myServiceFunction() = either {
  parZip(
    { someApiCall(...).bind() },
    { someOtherApiCall(...).bind() }
  ) { r1, r2 ->
       combineOperation(r1, r2) .bind()
    }
}
So here we simply call
parZip
inside
either
, which takes 3 functions
suspend () -> A
and
suspend () -> B
and another
(A, B) -> C
. This will run both functions in parallel, and then use the lambda to combine the results. If an
Either.Left
or exception is found then it’ll cancel both parallel operations.
👍 1
a
Great … thanks for the response 🙂 (we haven’t gone into the Fx so far … was getting the team used to the whole
Either
business and no exceptions 🙂 ) Now the fun starts getting springboot to play ball with this 😄
👍 1
s
I have used Arrow and Arrow Fx Coroutines with Spring Boot. I’d be happy to help with any questions you might have 🙂
Are you using WebFlux? Or just Spring Boot?
a
we’ve got just Springboot (with normal
RestController
and
RestTemplates
) however there’s no limitation to change to WebFlux if it’s needed
s
You can also achieve the same without using Arrow Fx Coroutines, but just using KotlinX Coroutines. (Arrow Fx Coroutines just offers some functional APIs and sugar on top of KotlinX Coroutines, so you can write
parZip
yourself too) https://github.com/arrow-kt/arrow/blob/main/arrow-libs/fx/arrow-fx-coroutines/src/commonMain/kotlin/arrow/fx/coroutines/ParZip.kt#L78
👍 1
a
we like the sugar 🙂
we’re getting
Copy code
No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
😕 1
s
What are you using to run suspend functions from a Controller? I was using this library, which a simple bridge between
DisposableBean
and
CoroutineScope
.
a
I definitely think that we’re not doing something correct in the controller … Which library were you using?
s
Hehe, forgot to add the link… 🤦 https://github.com/joost-de-vries/spring-coroutine
👍 1
This allows you to simply use the official KotlinX integration with
CompletableFuture
, and then in your controller you can just do
future { suspendFun() }
. https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-jdk8/
And this guarantees that if the code is still running when the controller shuts down that all the completable futures are also gracefully cancelled
a
Would switching to WebFlux make it simpler?
s
Haha, yes it’s a bit confusing 😅 I think WebFlux can make it simpler, yes. It has nicer support for Kotlin out-of-the-box, and it offers a bunch of functional APIs. There is however a bunch of other things to learn there, since it’s basically a new API. There is Project Reactor in all the APIs, so if your team is not familiar with that then that might also cause issues in learning curve etc.
a
Thanks … how much I dislike springboot 😂 Last project we were using vertx and everything was 🌻
👍 1
s
Haha 😄 I’ve not used VertX, but I’ve been using Ktor for a while and it’s also really nice. It has way less gotchas than Spring, don’t think I’ve encountered any actually. It’s writing in Kotlin, and has
suspend
APIs everywhere.
a
I’ve also played a bit with ktor and I like what I’m seeing 🙂 … would rather change to that however our client is hellbent on Springboot. Getting them to let us use kotlin was a big win 😄
s
Haha, gotta pick your battles 😛 In that case however I can recommend you to look into
coRouter
from
Spring WebFlux
. It has very similar API to Ktor’s
routing { }
DSL, and support coroutines out-of-the-box 😉 https://docs.spring.io/spring-framework/docs/current/kdoc-api/spring-framework/org.springframework.web.reactive.function.server/co-router.html
👍 2
a
Writing back with a status 🙂…switching to webflux and webclients definitely made our lifes easier (haven’t yet switched to
coRouter
as that would be the next step_
🙌 1
s
Great that that is working out for you! I’m happy to discuss any back-end tech, or help with any doubts if I can 👍
🙏 1
a
awesome 🙂 thank you so much for your help!
Hopefully I will also get more knowledge with this … so far I’ve only gotten quite comfortable modelling our domain with
Either
and also explaining it to all our new comers on the project. Actually the discussion to move away from exceptions is a very interesting one.
s
Using
suspend
+
Either
, and
Validated
/
Ior
which you can see as variants on
Either
is the most common use-case. Two other good ones are when you want to accumulate errors with
Validated
to validate a form or something, and
Ior
to collect both errors, and succeed values. For example for getting the results of
n
jobs. Arrow Fx Coroutines just adds some other cool stuff for concurrency on top of KotlinX Coroutines. CircuitBreaker, compose-able declarative Resource type, Schedule for repeating and retrying, and some sugar APIs for concurrent operations. That gives you a nice tool belt for building backends or apps. With Arrow going 1.0.0 , where going to be putting more time into docs etc so hopefully that’ll also help.
❤️ 1
a
Looking forward. If you need any help with proofreading I would love to help.
s
Awesome, thanks!
a
I really like that the first page gives info on what packages one needs. In the beginning I often got confused
s
Yes, that was one of the big improvements for me. We’re giving that some more love, and putting it on every landing page
a
I’ve spent hours explaining why we don’t just wanna throw 🙂
s
Long story short. throwing exceptions is like GOTO
a
yep … totally agreed (even mentioned this last year in a talk with a friend of mine

https://www.youtube.com/watch?v=ppN9nrh5Mu8

) #samelessplug 😛
🙌 1
s
Exceptions are typically use to avoid totality, or in other words if you don’t want to catch all cases and are too lazy to write the code
Domain Driven Design, FP, and a lot of OOP preaches to not do that. Make everything total, handle all cases, and don’t throw exceptions
plus one 1
It’s not specific to FP perse
a
leaky domain
s
But thanks for the feedback anyway, I put those things more in the background because they’re not really relevant to use Arrow Fx Coroutines. It’s just a companion to KotlinX Coroutines and it offers parallel operators and some interesting types such as
CircuitBreaker
,
Schedule
,
Resource
, some extensions on
Flow
. Those things are more like “Misc background information for those interested”, so it was my least prio 😅
I’ll see if I can improve it. Thanks!
a
I see … makes sense 🙂