Paul Woitaschek
11/06/2018, 12:23 PMCoroutineContext
when it's defined as the receiver on a supsending function inside a class?Tolriq
11/06/2018, 12:50 PMlaunch {
T1
val result = function()
T2
}
function is a suspend function that enqueue commands in a worker pool that works on Dispatchers.IO
supend function () : Result {
val result = workerpool.execute()
return result
]
The actual coroutine that run in the worker pool is just
doWork () : Result {
try {
T3
task.response.complete(response)
T4
} catch (e: Throwable) {
task.response.completeExceptionally(e)
}
]
And here's the threads the different parts run in on different runs.
1)
T1: Pre queue 81396 DefaultDispatcher-worker-5
T3: Pre task 81396 DefaultDispatcher-worker-5
T4: Post task 81396 DefaultDispatcher-worker-5
T2: Post queue 81366 DefaultDispatcher-worker-1
Why is T2 switched to another thread? I suppose the IO thread is asked for removal before the end of the coroutine to keep the number of default thread constants? Is this normal and efficient?
2)
T1: Pre queue 81375 DefaultDispatcher-worker-2
T3: Pre task 81417 DefaultDispatcher-worker-7
T4: Post task 81417 DefaultDispatcher-worker-7
T2: Post queue 81423 DefaultDispatcher-worker-12
Here the switch to IO really switched to another thread. Should not the thread be converted to IO as per the doc?
And same answer at the end why is there's another switch
Without looking at the thread switching all works and fast, just wondering if there's something I miss as I suppose on larger scale the switch can have impact and from the docs it seemed some should not happens.Paul Woitaschek
11/06/2018, 1:56 PMReceiveChannel#distinctUntilChanged
?jivimberg
11/06/2018, 3:40 PMmap
block (i.e. get to line 9) and then wait for the result.
Right now the await()
on line 6 is preventing me to do that.
Using CoroutineStart.LAZY
works but then I don’t get the nice parallel execution because each async only starts when it’s needed.Dias
11/06/2018, 4:26 PMPaul Woitaschek
11/06/2018, 7:59 PM* **Note**, that elements that are sent to this channel while there are no
* [openSubscription] subscribers are immediately lost.
napperley
11/06/2018, 9:07 PMkotlinx-coroutines-core.js:19616 TypeError: Cannot read property 'iterator' of undefined
at addAll (MutableCollections.kt:127)
at GroupStatistics.mainLanguage_e0v785$ (_Arrays.kt:8034)
at updateStatsLayout (main.kt:93)
at Coroutine$processFetchedRepos$lambda.doResume (main.kt:85)
at Coroutine$processFetchedRepos$lambda.CoroutineImpl.resumeWith_tl1gpc$ (CoroutineImpl.kt:47)
at CancellableContinuationImpl.DispatchedTask.run (kotlinx-coroutines-core.js:2682)
at WindowDispatcher$queue$ObjectLiteral.MessageQueue.process (kotlinx-coroutines-core.js:19877)
at kotlinx-coroutines-core.js:19846
groostav
11/07/2018, 12:13 AMchi
11/07/2018, 1:51 AMcountries.add(country)
launch(Dispatchers.Main) {
val exp = runExpensiveCode(country)
countries.remove(country)
if (exp != null) doAction()
}
suspend fun runExpensiveCode(country: Country) =
withContext(Dispatchers.Default) {
performVeryExpensiveAction(country) // legacy code used in several parts
}
This still freezes my main screen for some milliseconds, but the Async task implementation doesn't, how can I make this as seamless as possible?Dmytro Danylyk
11/07/2018, 3:57 AMkotlin
// library
class Componenet {
fun doSomething() {
launch { // long running operation }
}
}
// client
fun test() {
Componenet().doSomething()
// I want to wait until doSomething is finished but I can't
}
sdeleuze
11/07/2018, 9:22 AMnative-image
tool? I get a Non-instantiated type referenced by a compiled method: kotlin.Result$Companion
exception and I don't know if the issue is on Coroutines or Graal side https://github.com/oracle/graal/issues/783Colin
11/07/2018, 10:37 AMReceiveChannel
, and inside that function I am starting new suspended functions.
Pseudocode:
suspend fun produceStrings(): ReceiveChannel<String> {
return produce {
send(suspendedFunction1())
send(suspendedFunction2())
send(suspendedFunction3())
}
}
The code that calls produceStrings
is consuming the channel via consumeEach
. If at some point I cancel
the channel, I am expecting that the suspended functions inside the produce
block are stopped. i.e. I have a breakpoint in suspendedFunction3()
and I can see that the breakpoint is hit after I have cancelled the channel. Is this expected behaviour?yusuf3000
11/07/2018, 10:39 AMiosMain
but we cannot use it in commonMain
. We get a compilation error with Unresolved reference: GlobalScope
and the line it fails on is import kotlinx.coroutines.GlobalScope
.
Does anyone know why this is occurring and how we can fix this?plastiv
11/07/2018, 3:32 PMopen class RetrofitCallManager( // Open because its mocked at some unit tests.
val uiDispatcher: CoroutineDispatcher = Dispatchers.Main, // To be able to switch to Unconfined at jvm tests.
val ioDispatcher: CoroutineDispatcher = <http://Dispatchers.IO|Dispatchers.IO>
) : CoroutineScope {
private lateinit var parentJob: Job
override val coroutineContext: CoroutineContext
get() = parentJob + uiDispatcher
fun onCreate() {
parentJob = SupervisorJob() // Job is supervised so one failed child coroutine wouldn't cancel other running coroutines.
}
open fun <T> execute(request: NetworkRequest<Result<T>>, listener: ResultListener<T>) = launch { // Launch returns Job which could be joined inside test runBlocking.
try {
val result = withContext(ioDispatcher) {
request.loadDataFromNetwork() // Blocking retrofit network call.
}
if (result.isSuccess) {
listener.onResult(result.data()!!) // Update ui.
} else {
listener.onError(result.error()!!) // Update ui.
}
} catch (e: CancellationException) {
throw e // No need to propagate to UI since execution was cancelled by UI.
} catch (e: Exception) {
listener.onError(LocalError.create(ERR_CODE, e)) // Update ui.
}
}
fun onDestroy() {
parentJob.cancel()
}
}
Is this something you would expect to see in android app?dave08
11/07/2018, 4:07 PMwithContext
"swallow" exceptions like launch
?christophsturm
11/07/2018, 4:46 PMquiro
11/08/2018, 10:23 AMCaused by: java.lang.IllegalStateException: Module with the Main dispatcher is missing. Add dependency providing the Main dispatcher, e.g. 'kotlinx-coroutines-android'
quiro
11/08/2018, 10:24 AMmatej
11/08/2018, 1:44 PMjava.lang.IncompatibleClassChangeError: kotlinx.coroutines.io.internal.MutableDelegateContinuation
at kotlinx.coroutines.io.ByteBufferChannel.<init>(ByteBufferChannel.kt:2253)
at kotlinx.coroutines.io.ByteBufferChannel.<init>(ByteBufferChannel.kt:24)
at kotlinx.coroutines.io.ByteChannelKt.ByteChannel(ByteChannel.kt:13)
at kotlinx.coroutines.io.CoroutinesKt.writer(Coroutines.kt:98)
at io.ktor.util.cio.InputStreamAdaptersKt.toByteReadChannel(InputStreamAdapters.kt:21)
at io.ktor.util.cio.InputStreamAdaptersKt.toByteReadChannel$default(InputStreamAdapters.kt:20)
at io.ktor.client.engine.android.AndroidClientEngineKt.content(AndroidClientEngine.kt:117)
at io.ktor.client.engine.android.AndroidClientEngine.execute(AndroidClientEngine.kt:77)
at io.ktor.client.engine.android.AndroidClientEngine.access$execute(AndroidClientEngine.kt:21)
at io.ktor.client.engine.android.AndroidClientEngine$execute$2.invokeSuspend(AndroidClientEngine.kt:35)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:32)
at kotlinx.coroutines.DispatchedTask.run(Dispatched.kt:236)
at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:594)
at kotlinx.coroutines.scheduling.CoroutineScheduler.access$runSafely(CoroutineScheduler.kt:60)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:742)
Hadi Tok
11/08/2018, 4:02 PMDispatchers.Main
and I am getting java.lang.IllegalStateException: Module with the Main dispatcher had failed to initialize
I can provide Dispatchers.Main
externally or use Roboelectric but is there anything else that I can do?Slackbot
11/08/2018, 6:09 PMtateisu
11/08/2018, 6:31 PMtateisu
11/08/2018, 11:17 PMfun createCoroutineUnintercepted()
make Continuation<T>
from suspend code block
and completion: Continuation<T>
, but how it find coroutineContext for Continuation ?tateisu
11/09/2018, 6:26 AMBurkhard
11/09/2018, 10:13 AMTolriq
11/09/2018, 4:23 PMlaunch {
withContext(IO) { blockingCall() }
lock.release()
}
This can trigger a switch and one may want to optimize to:
launch(IO) {
blockingCall()
lock.release()
}
Is there any interest to do that? Or is it better to keep clear separation between blocking calls on IO and non blocking calls?Slackbot
11/10/2018, 6:47 PMpakoito
11/10/2018, 7:53 PMdave08
11/11/2018, 2:02 PMConcurrentHashMap
with coroutines that suspends the current Coroutine instead of blocking the thread? Sometimes retrieval of missing values can take time...Romain
11/12/2018, 7:20 AMRomain
11/12/2018, 7:20 AMtateisu
11/12/2018, 11:50 AMRomain
11/13/2018, 4:44 PM