Created
February 28, 2019 08:15
-
-
Save sitepodmatt/b3a7a53ff1f17c23e08f0ccb052cf989 to your computer and use it in GitHub Desktop.
example.kt
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
import io.kotlintest.specs.StringSpec | |
import kotlinx.coroutines.* | |
import kotlin.coroutines.CoroutineContext | |
class RequestContextTest : StringSpec({ | |
"playing with human context" { | |
try { | |
runBlocking { | |
val result = async("Processing web request") { | |
val i1 = async<String>("fetching image 1") { | |
launch("some off shot task somewhere deep") { | |
delay(20) | |
throw Exception("poo") | |
} | |
delay(200) | |
"image1" | |
} | |
val i2 = async<String>("fetching image 2") { | |
delay(100) | |
"image2" | |
} | |
i1.await() + " : " + i2.await() | |
} | |
} | |
} catch (ce: ContextualException) { | |
println(ce) | |
println("Job trace: " + ce.getJobTrace()) | |
} | |
} | |
}) | |
fun CoroutineScope.launch(aboutMsg: String, block: suspend CoroutineScope.() -> Unit): Job { | |
return launch { | |
contextMap[this.coroutineContext[Job]!!] = aboutMsg | |
try { | |
block() | |
} catch (t: Throwable) { | |
when (t) { | |
is ContextualException -> throw t | |
else -> throw ContextualException(this.coroutineContext[Job]!!, t.message!!, t) | |
} | |
} | |
} | |
} | |
fun <T> CoroutineScope.async(aboutMsg: String, block: suspend CoroutineScope.() -> T): Deferred<T> { | |
return async<T> { | |
contextMap[this.coroutineContext[Job]!!] = aboutMsg | |
try { | |
block() | |
} catch (t: Throwable) { | |
when (t) {a | |
is ContextualException -> throw t | |
else -> throw ContextualException(this.coroutineContext[Job]!!, t.message!!, t) | |
} | |
} | |
} | |
} | |
class ContextualException(val jobCause: Job, msg: String, t: Throwable) : Exception(msg, t) | |
// move on to somecouroutineelement maybe along side Job? | |
val contextMap = mutableMapOf<Job, String>() | |
fun ContextualException.getJobTrace(): List<String> { | |
var job: Job? = this.jobCause | |
val list = mutableListOf<String>() | |
while (job != null) { | |
list.add(contextMap[job] ?: job.toString()) | |
job = job.getParent() | |
} | |
return list.also { it.reverse() } | |
} | |
@UseExperimental(InternalCoroutinesApi::class) | |
fun Job.getParent(): Job? { | |
return (AbstractCoroutine::class.java as Class<*>)?.getDeclaredField("parentContext") | |
?.also { it.isAccessible = true }?.let { it.get(this) as? CoroutineContext? }?.let { it[Job] } | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment