Race two computations
A number of computations can be raced against each other using the race
method, for example:
import ox.{race, sleep}
import scala.concurrent.duration.*
def computation1: Int =
sleep(2.seconds)
1
def computation2: Int =
sleep(1.second)
2
val result: Int = race(computation1, computation2)
// 2
The losing computation is interrupted. race
waits until both branches finish; this also applies to the losing one,
which might take a while to clean up after interruption.
It is also possible to race a sequence of computations, given as Seq[() => T]
.
Race variants
race
returns the first result, or re-throws the last exceptionraceResult
returns the first result, or re-throws the first exception (the first computation which finishes in any way is the “winner”)
Using application errors
Some values might be considered as application errors. In a computation returns such an error, race
continues waiting
if there are other computations in progress, same as when an exception is thrown. Ultimately, race
either throws
the first exception, or the first application error that has been reported (whichever comes first).
It’s possible to use an arbitrary error mode by providing it as the initial argument to race
.
Alternatively, a built-in version using Either
is available as raceEither
:
import ox.{raceEither, sleep}
import scala.concurrent.duration.*
raceEither({
sleep(200.millis)
Left(-1)
}, {
sleep(500.millis)
Right("ok")
}, {
sleep(1.second)
Right("also ok")
})
Here, the example returns Right("ok")
; the first result is considered an error (a Left
), and the third computation
is cancelled.