Hello, can I pass kotlin coroutine scope as functi...
# coroutines
v
Hello, can I pass kotlin coroutine scope as function argument? I have created question about it: https://stackoverflow.com/questions/61606630/should-you-pass-coroutinescope-as-function-argument
o
FYI,
execute(coroutineScope: CoroutineScope, bitmap: Bitmap)
is the same as
CoroutineScope.execute(bitmap: Bitmap)
in terms of bytecode
the only difference is the source code calling convention
I'm not sure what memory leaks you're worried about, coroutines become unreachable after they finish executing -> GC can clean them up
unfortunately I'm not very well versed in android MVVM so I'm not quite sure what the exact issue is, but hopefully this clears some stuff up
v
Yes, I thought that it would be same in terms of bytecode. But why CoroutineScope.execute(bitmap: Bitmap) is not visible to call from another class?
o
depends on how you're calling it, I would have to see the code. It should be available, but extension functions inside classes (i.e. not top-level) are a little quirky
v
ok, I will edit my post in a minute :)
I edited post
Regarding leaks, I know how coroutines work, however, I have my doubts about passing coroutine context into regular classes. I have not seen such examples. But it does make sense in our case, because that execute function is actually much larger with more context switching and even async await call.
o
the memory model for coroutines is pretty simple, it's essentially the same as the existing model, just when the function is suspended the local variables are held by a Continuation instance. when the Continuation is no longer referenced (either because it was resumed, or the thing holding it was itself unreferenced), everything related to the function is GC-able
👍 1
I posted an answer to the question of why it's not accessible
v
yes, thanks this issue is solved 🙂I really appreciate it... Now regarding using launch in usecase you could be right... However, I need to call async await in my launch block. If I make execute suspending function I can't call async await without launch block... Or is there a way to call async await in suspending function, without launch block?
o
you should probably read up on structured concurrency https://medium.com/@elizarov/structured-concurrency-722d765aa952
v
oh, thanks. Now I see why I can't do it with regularly, without wrapping my async await code in coroutineScope... However, this newly created coroutineScope is still managed by my outer scope, which was created with launch in VM, yes_*?*_
o
depends on what you mean by managed, the outer scope will be the parent of the inner scope, partially explained at https://kotlinlang.org/docs/reference/coroutines/coroutine-context-and-dispatchers.html#children-of-a-coroutine
v
Bad formating sorry
Will create a gist for this case
Here, I will write test for this code, but so far it executes what I need. Create a long running task with withContext, wait for result and then spawn 3 parallel tasks. 2 of them are needed for await because I need results for starting a network request. 1 is not needed for await. It can take longer time for running. And then after all is done notify my repository about some changes
o
this is mentioned in the structured concurrency docs, but
coroutineScope {}
will wait until all things started inside are completed
v
I am just confused about this part, which spawns async calls:
Copy code
coroutineScope{
}
If I call this suspend fun with viewModelScope.launch{ } that means that coroutineScope inherits viewModelScope, yes? :)
o
I think inherits is the wrong word here
v
what would be more appropriate?
o
coroutineScope {}
really knows nothing about the
viewModelScope
, it will just take the current
coroutineContext
+
Job(coroutineContext[Job])
and create a new scope with those elements
it is some ancestor of `viewModelScope`'s
Job
, but it may not necessarily have anything else in common with it (such as dispatcher)
v
oh, I see... so it might not be appropriate in my case..
o
I think it is, except for that last one which you're not
await
ing
if you want that to continue in parallel, you will need to get some sort of application scope (maybe
viewModelScope
is appropriate here) and
launch
it there
but running it based on the
coroutineScope {}
-created scope will cause your function to suspend at the end of the block until every child Job is done
👍 1
v
viewModelScope acts as application scope in our case, because of SingleActivity.
Thanks.. now I get it! Like really,.. you should write some medium posts 😄 Now that you said, I still need to pass viewModelScope(same as applicationScope) as function argument to make sure that last one job is done in parallel instead of using coroutineScope, which requires to wait... yes? :D
o
yes
v
Hmm, perhaps I found a better solution. Played right now. If I directly pass applicationscope instead of using coroutineScope I would not need to launch coroutine 2 times. I could do everything in one scope, running in parallel. https://gist.github.com/wellbranding/5557c920e28b11097f6d163272aa7cbe