-
Notifications
You must be signed in to change notification settings - Fork 451
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Racing DSL #3411
base: main
Are you sure you want to change the base?
Racing DSL #3411
Conversation
Kover Report
|
arrow-libs/fx/arrow-fx-coroutines/src/commonMain/kotlin/arrow/fx/coroutines/Racing.kt
Show resolved
Hide resolved
arrow-libs/fx/arrow-fx-coroutines/src/commonMain/kotlin/arrow/fx/coroutines/Racing.kt
Show resolved
Hide resolved
try { | ||
block() | ||
} catch (e: RaiseCancellationException) { | ||
// `Raise<E>` error is ignored... Can we do better here? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe raise
shouldn't be considered a failure? Perhaps raising in such a way is conceptually the same as return
ing a value. Alternatively, we can have a raceOrRaise
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe raise shouldn't be considered a failure? Perhaps raising in such a way is conceptually the same as returning a value. Alternatively, we can have a raceOrRaise
Hmm. That kind-of makes sense, but I'd still expect user to want to 'select' E
and not A
but supporting both would be great.
So how do you imagine the API:
- race (first
A
) - raceOrRaise ( first
A
orE
) - raceOrThrow (first
A
,E
orThrowable
)
?? Do we need something that 'selects' first A
or Throwable
?
Potentially we can do a different extension when you reside within Raise
, so an extension Raise<E>.racing(...)
but then it's probably still possible to easily select the non-Raise variant 🤔.
suspend fun Raise<E>.racing(...): A
suspend fun racing(..): A
This probably doesn't yield the benefit we'd want since the non-Raise racing
would get suggested when Raise
doesn't match or Raise.racing
has an additional param.
@serras I added a 2.x.x label, and this can come after 2.0.0. Since it's a new API/DSL. |
Can we somehow integrate this with |
Not sure whether to love or hate what I've created:
The idea is simple: no custom receiver type. Instead, we want to have in context a |
That previous comment forgot to cancel the other deferreds when the selection is over, which sounds suspiciously similar to releasing a resource:
|
This PR proposes a small racing DSL, it comes up several times in discussions and comparison with different ecosystems.
Racing and stopping at the first value is desired in many cases, often lower level or UI development. This kind of racing is often a 'forever' kind-of operation, versus an actual operation.
race(::showLoader, ::loadData)
where you want to cancelshowLoader
when the data is loaded.race(interruption, operation)
whereoperation
needs to be cancelled wheninterruption
is completed.This however doesn't represent what we often want to do in application code, which is get successful results. So another popular use-case for racing is fetching data from x sources in parallel, and finish on the first successful results. That also means that if a source cannot be reached, we want to ignore that exception.
Having to manually facilitate the second use-case on top of the first one is a bit annoying, and boilerplatey.
This DSL aims to solve that by serving both use-cases, and allowing more flexibility to combine two techniques into a single program. It uses a DSL, so allows for more efficient re-using of the underlying state machines from KotlinX and fits right into the rest of Arrow (and Kotlin, including context parameters).
I propose to not remove
raceN
, but to let it exist alongside the newracing
DSL. We currently only support race2, and race3 so the combined amount of code is not problematic IMO.TODO