Last active
December 21, 2018 06:42
-
-
Save ilya-g/314c50369d87e0740e976818d2a09d3f to your computer and use it in GitHub Desktop.
Cancellation support interceptor
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
class JobCancellationInterceptor(val originalInterceptor: ContinuationInterceptor?) : | |
AbstractCoroutineContextElement(ContinuationInterceptor), | |
ContinuationInterceptor { | |
override fun <T> interceptContinuation(continuation: Continuation<T>): Continuation<T> = | |
CancellableCheckContinuation(continuation).let { | |
originalInterceptor?.interceptContinuation(it) ?: it | |
} | |
class CancellableCheckContinuation<T>(val continuation: Continuation<T>) : Continuation<T> { | |
override val context: CoroutineContext get() = continuation.context | |
override fun resume(value: T) { | |
val job = context[Job] | |
if (job?.isCompleted == true) { | |
println("Cancelling continuation, because job is already completed") | |
continuation.resumeWithException(job.getCompletionException()) | |
} else { | |
continuation.resume(value) | |
} | |
} | |
override fun resumeWithException(exception: Throwable) = | |
continuation.resumeWithException(exception) | |
} | |
} | |
fun CoroutineContext.addCancellationInterceptor(): CoroutineContext = this + JobCancellationInterceptor(this[ContinuationInterceptor]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment