Skip to content

Instantly share code, notes, and snippets.

@nomisRev
Last active February 27, 2023 19:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nomisRev/47625c374c2382f534ee8c50a6a7d72d to your computer and use it in GitHub Desktop.
Save nomisRev/47625c374c2382f534ee8c50a6a7d72d to your computer and use it in GitHub Desktop.
POC Race Design
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