if a have a this ```myScope (supervisor + Main + ...
# coroutines
j
if a have a this
Copy code
myScope (supervisor + Main + interceptor)

myScope.launch {
  text = mySusFunc()
}

suspend fun mySusFunc(): String {
return withContext(<http://Dispatchers.IO|Dispatchers.IO>) {
          delay(1000)
         "myValue"
  }
}
Would the attribution
text =
always happen in the Main ? Because from some experimenting here, it looks like it happens from the IO thread. Help ?
j
Yes, the assignment should happen in
Main
, if
myScope
uses
Main
as dispatcher. But if other pieces of the context in
myScope
override the dispatcher, it would be that dispatcher instead.
s
What is
interceptor
?
j
I will try to create a sample app...
s
A dispatcher is a type of continuation interceptor. So if you replace the interceptor in the context, you are actually replacing/removing the dispatcher.
1
j
How can I fix that ?
s
Make your custom interceptor be a decorator on top of the dispatcher you want to use
j
Sorry, I don't understand... decorator ?
s
In
interceptContinuation
, instead of just returning the continuation, pass it to another interceptor first (which will be the dispatcher) e.g.
Copy code
private class MyInterceptor(
    private val dispatcher: CoroutineDispatcher,
) : ContinuationInterceptor {
    override val key: CoroutineContext.Key<*>
        get() = ContinuationInterceptor

    override fun <T> interceptContinuation(continuation: Continuation<T>): Continuation<T> {
        // do your interceptor stuff here
        return dispatcher.interceptContinuation(continuation);
    }
}
j
ahhhhh
s
("decorator" refers to the decorator design pattern)
👀 1
j
s
👍 looks right to me! One thing to note: you could change
Copy code
SupervisorJob() +
    Dispatchers.Main.immediate +
    viewScopeInterceptor(Dispatchers.Main.immediate)
to just
Copy code
SupervisorJob() + viewScopeInterceptor(Dispatchers.Main.immediate)
because the view scope interceptor will replace the dispatcher as soon as you add it (they have the same key in the coroutine context)
j
ok, thank you very much. I thought that
+
would be cumulative and not replace things...
s
A coroutine context can only ever have one of each "type" of context element. It's a bit like a map where the key is the type of element.
j
humm... ok, but.... I did create a new type for this
ContinuationInterceptor
and It is just that when I read
ContinuationInterceptor
I think that I can have a chain of it...
s
The key/"type" of a continuation interceptor as far as the coroutine context is concerned is always just
ContinuationInterceptor
😞 (e.g. in your code):
Copy code
override val key: CoroutineContext.Key<*>
        get() = ContinuationInterceptor
I don't know of anything in the coroutines standard library that lets you make a chain of interceptors, sadly
j
should I have used the key from the decorated CoroutineDispacher ?
s
Your code is correct as far as the key is concerned. The key is always going to be same. That's just how you tell Kotlin that it is a ContinuationInterceptor. If you go and look at the implementation of
CoroutineDispatcher
, it has the same key as well.
j
ok, thanks for the help
blob smile 1