https://kotlinlang.org logo
#coroutines
Title
# coroutines
b

bloder

04/09/2019, 2:32 AM
Hey Guys! Is there a way to do concurrency using the same coroutine context?
async
is not working (newbie question probably)
g

gildor

04/09/2019, 2:38 AM
Could you provide some example or describe what you want to achieve
b

bloder

04/09/2019, 2:45 AM
I'm having problems changing my coroutine context, some times the block is not called when I change the context (
withContext(<http://Dispatchers.IO|Dispatchers.IO>) {}
): I have an app and a implementation of pull to refresh, and when user refreshes it the app makes some requests and the view updatings, but when I refresh like 4 or 5 times my requests that are in blocks of a
withContext(<http://Dispatchers.IO|Dispatchers.IO>)
is not called but when I use my coroutine context it works...
g

gildor

04/09/2019, 2:46 AM
Hard to say without code samples
b

bloder

04/09/2019, 2:46 AM
hmmm just a sec
g

gildor

04/09/2019, 2:46 AM
what looks suspicious is that you use
withContext(<http://Dispatchers.IO|Dispatchers.IO>)
which is probably wrapping some blocking code, so request is probably not cancellable
b

bloder

04/09/2019, 2:49 AM
Copy code
fun fetchInformation(informationType: InformationType = lastInformationType) = launch {
        view?.showLoading()
        view?.hideEmptyState()
        view?.hideAddressEmptyState()

        lastInformationType = informationType

        val dishPartialInformationDeferred = withContext(<http://Dispatchers.IO|Dispatchers.IO>) { // this block is not called when fetchInformation is called 4 or 5 times  }
}
ohh sorry about the indentation
g

gildor

04/09/2019, 2:50 AM
I see that you return Job, are you sure that you do not cancel it
b

bloder

04/09/2019, 2:51 AM
but basically
dishPartialInformationDeferred
withContext block is not called on 4 or 5 invoke of the function
g

gildor

04/09/2019, 2:51 AM
I don’t think so
it may happen only if coroutine is cancelled
what if you call fetchInformation multiple times, it will start a few concurrent cororutines, maybe it somehow broke your state
b

bloder

04/09/2019, 2:53 AM
yeahh I thought in something like that, do u recomend a better implementation for functions that will be called multiple times?
g

gildor

04/09/2019, 2:57 AM
Depends on how you want this function work, if just cancel previous request ie may be like this:
Copy code
fun fetchInformation(informationType: InformationType = lastInformationType) {
       fetchJob?.cancel()
       fetchJob = launch {
        view?.showLoading()
        …
       }
}
b

bloder

04/09/2019, 2:58 AM
yeahh I'm going to try to cancel it
g

gildor

04/09/2019, 3:02 AM
I don’t know what you do in dishPartialInformationDeferred, but if it’s blocking (which is most probably, because you use IO dispatcher), it will not be cancelled and will finish
b

bloder

04/09/2019, 3:04 AM
cancelling doesn't work, in dishPartialInformationDeferred there're some requests that I use IO dispatcher
weird... the block of
withContext(<http://Dispatchers.IO|Dispatchers.IO>)
is not been called and I'm cancelling the job
g

gildor

04/09/2019, 3:07 AM
is not been called
How do you check this?
try check Job state before calling this
It looks that you do something with Job or Scope lifecycel there and cancel job
check that you do not have exceptions
b

bloder

04/09/2019, 3:13 AM
no I don't have exceptions stop to work on the invoke of the function... example if I use
async(<http://Dispatchers.IO|Dispatchers.IO>)
stops on
await
call
Are u using coroutines in your apps? Did u already have implemented a solution of pull to refresh using coroutines? Probably I'm doing something wrong, but I can't see what, I'm just doing some requests using IO dispatcher inside a launcher and creating this launcher every time user refresh the app
g

gildor

04/09/2019, 3:17 AM
yes I do
I just launch request and everything work, also cancel previous one
It’s nothing to do with IO dispatcher I believe
example if I use
async(<http://Dispatchers.IO|Dispatchers.IO>)
stops on
await
call
What do you mean?
b

bloder

04/09/2019, 3:18 AM
are u cancelling all jobs including the jobs that are executed on IO context?
oh forget it, it's just not calling the block, without throwing an exception
g

gildor

04/09/2019, 3:21 AM
so it actually throws exception?
are u cancelling all jobs including the jobs that are executed on IO context?
Dispatcher is just about thread on which job will be called, cancellation strategy is the same. But blocking code by itself cannot be cancelled
b

bloder

04/09/2019, 3:22 AM
no, it's not throwing any exception
ohh I'm going to try to find a solution here, like I said probably I'm doing something wrong, just need to see what, the weird is when I execute all on the same coroutine context it's work
g

gildor

04/09/2019, 3:24 AM
Again, how do you know that withContext block is not called?
b

bloder

04/09/2019, 3:24 AM
well I'm debugging and I put some log inside that
and it's not been called or logged
g

gildor

04/09/2019, 3:25 AM
debugging is probably not the best solution, it’s not so reliable with coroutines
log is fine
also log Job state
b

bloder

04/09/2019, 3:25 AM
ok I'm going to try log the state of job
g

gildor

04/09/2019, 3:25 AM
just do
println("Job: ${coroutineContext[Job]}")
👍 1
also maybe some code inside of withContext just hanging
If you would share some self contained sample it would be helpful
b

bloder

04/09/2019, 4:05 AM
Just to say that it's fixed... it was a problem with a counter that had a job and it was cancelling the job and probably in some time my requests jobs was being part of the counter job tree and it was being cancelled
thanks to helping man!
👍 1
g

gildor

04/09/2019, 4:11 AM
Yeah, that what I expected, that Job/Scope is actually cancelled
But why your counter cancel the job? What is your usecase?
b

bloder

04/09/2019, 4:15 AM
that's what I'm trying to figure out
Sorry for the delay, but I believe the problem was that in my counter the coroutines was created in a Global Scope (I always say to my team don't use that hahaha) and probably some times this scope was cancelling my other jobs
I just have changed this scope to a structured scope and it's working... Thanks for helping!
👍 1