sam
08/08/2019, 7:44 PMwhile (true) { consumer.take() }
, where consumer.take is a blocking call on a JMS client. Normally, I’d launch a new thread for this, and then shut down the thread once the program exits.octylFractal
08/08/2019, 7:48 PM<http://Dispatchers.IO|Dispatchers.IO>
thread pool, which has a lot of extra threads that can be blocked, or you might want to have your own thread pool with a similarly high number of threads.
In any case, I would yield()
after every take()
to participate in cooperative cancellation, but otherwise, the loop is still how you handle this in coroutines.
If you wanted to also run some code inside the loop, you might send the data over Channel
-- do yourIOScope.produce { while (true) channel.send(consumer.take()) }
, and then use the resulting channel to retrieve results when you need them, in a suspending manner. But it all depends on your use case.sam
08/08/2019, 7:52 PMlouiscad
08/08/2019, 7:52 PMwhile (isActive)
if the semantics suit your use case well.sam
08/08/2019, 7:53 PMoctylFractal
08/08/2019, 7:53 PMCoroutineScope(your-dispatcher)
sam
08/08/2019, 7:55 PMval dispatcher = Executors.newSingleThreadExecutor().asCoroutineDispatcher()
CoroutineScope(dispatcher).launch {
while (true) {
val messages = consumer.poll(Duration.ofSeconds(5))
}
}
louiscad
08/08/2019, 7:55 PMisActive
will not block it but will not let other coroutines run cooperatively on the same dispatcher as yield() or other suspending and dispatching function would.sam
08/08/2019, 7:56 PMsam
08/08/2019, 7:57 PMisActive
here will check that the coroutine is still running, how does that help with cooperation, I’m not clear on thatlouiscad
08/08/2019, 8:09 PMsam
08/08/2019, 8:10 PMsam
08/08/2019, 8:12 PMoctylFractal
08/08/2019, 8:13 PMsam
08/08/2019, 8:13 PMsam
08/08/2019, 8:17 PMyou gain the ability to suspend in other contexts for the same call
can you explain that ?octylFractal
08/08/2019, 8:19 PMval messages = CoroutineScope(dispatcher).produce {
while (true) {
channel.send(consumer.take())
}
}
in another coroutine, you can do messages.receive()
(or similar call) to suspend for the result of consumer.take
. it will still block the single-thread-dispatcher, but it won't block other threads that use receive()
sam
08/08/2019, 8:19 PMoctylFractal
08/08/2019, 8:19 PMsam
08/08/2019, 8:20 PMoctylFractal
08/08/2019, 8:23 PMwithContext
calls in your code, switching from your blocking thread to e.g. a UI thread (not sure if that's relevant to you)octylFractal
08/08/2019, 8:24 PMsam
08/08/2019, 8:24 PMsam
08/08/2019, 8:26 PMoctylFractal
08/08/2019, 8:27 PMproduce(capacity = 1)
sam
08/08/2019, 8:27 PMoctylFractal
08/08/2019, 8:28 PMsam
08/08/2019, 8:29 PMsam
08/08/2019, 8:29 PM