mcastiblanco
02/19/2018, 3:08 AMJob
that sends a batch of analytics every certain time. Sending analytics should not return anything and thus is a perfect case for a Job
. Every so often I may want to check that the Job has completed without exceptiongildor
02/19/2018, 3:08 AMUnit
value, it’s completely validgildor
02/19/2018, 3:09 AMgildor
02/19/2018, 3:09 AMmcastiblanco
02/19/2018, 3:10 AMgildor
02/19/2018, 3:10 AMgildor
02/19/2018, 3:10 AMgildor
02/19/2018, 3:11 AMmcastiblanco
02/19/2018, 3:12 AMDeferred<Unit>
, but I think that it may be good to have such a property so that whenever someone wants to validate that their Job ended without exception they are not forced to change their code to use Deferred<Unit>
or to validate the message of the CancellationException
mcastiblanco
02/19/2018, 3:12 AMmcastiblanco
02/19/2018, 3:13 AMgildor
02/19/2018, 3:15 AMgildor
02/19/2018, 3:23 AMevery scenario that I can think of can be replaced with aNot every. There are different reasons for uncaught exception and you want just crash an app. But Deferred user can do not handle result and ignore error, it’s completely client responsibility.Deferred<Unit>
mcastiblanco
02/19/2018, 3:39 AMMichael Kotlikov
02/19/2018, 6:29 AMsuspend fun <T> asyncResult(execute: () -> T): T {
data class AsyncResponse<T>(val result: T?, val exception: Exception?)
val responseChannel = Channel<AsyncResponse<T>>()
val asyncResponse: AsyncResponse<T>?
CompletableFuture.runAsync {
try{
val executionResult = execute()
launch(NoopContinuation.context) {
responseChannel.send(AsyncResponse(
result = executionResult,
exception = null
))
}
} catch(exception: Exception) {
launch(NoopContinuation.context) {
responseChannel.send(AsyncResponse(
result = null,
exception = exception
))
}
}
}
asyncResponse = responseChannel.receive()
if (asyncResponse.exception != null) {
throw asyncResponse.exception
}
return asyncResponse.result!!
}
Michael Kotlikov
02/19/2018, 6:30 AMnewSingleThreadContext()
instead?
https://github.com/Kotlin/kotlinx.coroutines/blob/master/coroutines-guide.md#dispatchers-and-threadsSergey Chikin
02/19/2018, 9:20 AMasync
coroutine builder, in other words in your code instead of calling asyncResult {lambda}
you can do simply async {lambda}
and not even build this function. You can specify where the coroutine will be executed by passing CoroutineContext
to async
like this: async(routineContext) { lambda }
, where I have routineContext
defined as follows:
internal val routineContext: CoroutineContext by lazy {
log.debug("Initializing pool with configuration $configuration")
when (configuration) {
is SingleThreadConfiguration -> newSingleThreadContext(configuration.name)
is FixedThreadPoolConfiguration -> newFixedThreadPoolContext(configuration.threads, configuration.name)
is CachedThreadPoolConfiguration -> CachedCoroutineDispatcher(configuration.name)
is ForkJoinPoolConfiguration -> ForkJoinCoroutineDispatcher(configuration.name, configuration.parallelism)
else -> throw ConfigurationException("Unknown thread pool requested")
}
}
Sergey Chikin
02/19/2018, 9:21 AMCoroutineContext
Sergey Chikin
02/19/2018, 9:23 AMnewSingleThreadContext
and newFixedThreadPoolContext
provided by coroutines library out of box, and you can construct your own CoroutineContext
based on any ExecutorService
like this:
open class BaseCoroutineDispatcher(private val executor: ExecutorService) : CoroutineDispatcher() {
override fun dispatch(context: CoroutineContext, block: Runnable) {
executor.execute(block)
}
}
Michael Kotlikov
02/19/2018, 9:39 AMCachedCoroutineDispatcher
the same as Java's native newCachedThreadPool
under-the-hood or will I need to roll my own CoroutineContext
?Michael Kotlikov
02/19/2018, 11:04 AMfun newCachedThreadPoolContext() = CachedThreadPoolDispatcher(Executors.newCachedThreadPool())
class CachedThreadPoolDispatcher(private val executor: Executor) : ExecutorCoroutineDispatcherBase() {
override fun dispatch(context: CoroutineContext, block: Runnable) = executor.execute(block)
}
What about this with a static cachedThreadPool?
fun newCachedThreadPoolContext() = CachedThreadPoolDispatcher()
class CachedThreadPoolDispatcher : ExecutorCoroutineDispatcherBase() {
companion object {
private val executor = Executors.newCachedThreadPool()!!
}
override fun dispatch(context: CoroutineContext, block: Runnable) = executor.execute(block)
}
pakoito
02/19/2018, 11:07 AMis it a premature optimization to check and not start a coroutine on a CorroutineContext if it’s going to be on the same context as the current one, and use EmptyCoroutineContext insteadasking question from yesterday
jw
02/19/2018, 6:23 PMjw
02/19/2018, 6:23 PMjw
02/19/2018, 6:23 PMOlekss
02/20/2018, 8:39 AMacando86
02/20/2018, 10:28 AMJonathan
02/20/2018, 10:37 AMPaul Woitaschek
02/20/2018, 3:50 PMPaul Woitaschek
02/20/2018, 3:50 PM