Last active
December 21, 2018 06:42
Star
You must be signed in to star a gist
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