Last active
February 27, 2023 19:15
-
-
Save nomisRev/47625c374c2382f534ee8c50a6a7d72d to your computer and use it in GitHub Desktop.
POC Race Design
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
sealed interface RaceRes<A, B> | |
data class First<A>(val first: A): RaceRes<A, Nothing> | |
data class FirstWithFailure<A>(val first: A, val second: Throwable): RaceRes<A, Nothing> | |
data class Second<B>(val second: B): RaceRes<Nothiing, B> | |
data class SecondWithFailure<B>(val first: Throwable, val second: B): RaceRes<Nothing, B> | |
/** | |
* raceSuccess({ req(0) }) { req(0) }).merge() | |
* What to do with exceptions?? RaceRes seems very clumsy. | |
*/ | |
suspend fun <A, B> raceSuccess( | |
fa: suspend () -> A, | |
fb: suspend () -> B | |
): RaceRes<A, B> = TODO("Ox / ZIO API") | |
/** | |
* raceSuccess({ req(0) }) { req(0) }).merge() | |
* Takes handler for swallowed exceptions, or prints their stacktrace if empty. | |
*/ | |
suspend fun <A, B> raceSuccess( | |
coroutineExceptionHandler: CoroutineExceptionHandler, | |
fa: suspend () -> A, | |
fb: suspend () -> B | |
): Either<A, B> = raceSuccess(defaultExceptionHandler(), fa, fb) | |
suspend fun <A, B> raceSuccess( | |
fa: suspend () -> A, | |
fb: suspend () -> B | |
): Either<A, B> = raceSuccess(defaultExceptionHandler(), fa, fb) | |
/** | |
* racing { | |
* raceSuccess { req(0) } | |
* raceSuccess { req(0) } | |
* | |
* repeat(10_000) { | |
* raceSuccess { req(0) } | |
* } | |
* } | |
*/ | |
suspend fun racing( block: RaceScope<A>.() -> Unit): A = racing(defaultExceptionHandler(), block) | |
suspend fun racing( | |
coroutineExceptionHandler: CoroutineExceptionHandler, | |
block: RaceScope<A>.() -> Unit | |
): A = TODO("Racing DSL") | |
interface RaceScope<A> { | |
val coroutineExceptionHandler: CoroutineExceptionHandler | |
suspend fun race(block: () -> A): Unit = TODO("Implement with select") | |
/** Racer that is ignore if it failed */ | |
suspend fun raceSuccess(block: () -> A): Unit = | |
race { | |
try { | |
block() | |
} catch(e: Throwable) { | |
handler.handleException(currentCoroutineContext(), e.nonFatalOrThrow()) | |
awaitCancellation() | |
} | |
} | |
} | |
private suspend fun defaultExceptionHandler(): CoroutineExceptionHandler = | |
currentCoroutineContext()[CoroutineExceptionHandler] ?: DefaultCoroutineExceptionHandler | |
private object DefaultCoroutineExceptionHandler : CoroutineExceptionHandler() { | |
override fun handleException(context: CoroutineContext, exception: Throwable) { | |
if(exception !is CancellationException) exception.printStackTrace() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment