Hey Guys! Is there a way to do concurrency using t...
# coroutines
b
Hey Guys! Is there a way to do concurrency using the same coroutine context?
async
is not working (newbie question probably)
g
Could you provide some example or describe what you want to achieve
b
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
Hard to say without code samples
b
hmmm just a sec
g
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
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
I see that you return Job, are you sure that you do not cancel it
b
but basically
dishPartialInformationDeferred
withContext block is not called on 4 or 5 invoke of the function
g
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
yeahh I thought in something like that, do u recomend a better implementation for functions that will be called multiple times?
g
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
yeahh I'm going to try to cancel it
g
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
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
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
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
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
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
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
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
Again, how do you know that withContext block is not called?
b
well I'm debugging and I put some log inside that
and it's not been called or logged
g
debugging is probably not the best solution, it’s not so reliable with coroutines
log is fine
also log Job state
b
ok I'm going to try log the state of job
g
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
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
Yeah, that what I expected, that Job/Scope is actually cancelled
But why your counter cancel the job? What is your usecase?
b
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