https://kotlinlang.org logo
#coroutines
Title
# coroutines
w

withoutclass

08/24/2018, 6:23 PM
They don’t work for me when I’m reading in batches
l

louiscad

08/24/2018, 6:25 PM
Why so? I'm not sure I understand what you do exactly
w

withoutclass

08/24/2018, 6:25 PM
Making a quick example
l

louiscad

08/24/2018, 6:26 PM
Explaining what you want to do is also useful information
w

withoutclass

08/24/2018, 6:30 PM
So I have an
Activity
that alters it’s state/responds to information received from incoming bluetooth packets. I do not want to thrash the UI, so I want to read in all the packets, then delay some time before checking to see if there are more packets.
Copy code
internal suspend fun listenForPackets(packetBroadcastChannel: BroadcastChannel<Packet>, 
    activityActionChannel: SendChannel<Action>) {
    val packetReceiveChannel = packetBroadcastChannel.openSubscription()
    try {
        while (isActive) {
            delay(4000)
            var count = 0
            while (!packetReceiveChannel.isEmpty) {
                packetReceiveChannel.receive()
                count++
            }

            when (count) {
                0 -> activityActionChannel.send(Action.DoThing)
            }

        }
    } finally {
        withContext(NonCancellable) {
            packetReceiveChannel.cancel()
        }
    }
}
this is where I landed after discovering the requirement to call cancel in a finally block.
In essence, I want to “batch” read all packets from the channel till it’s empty, then delay for some time before doing so again
l

louiscad

08/24/2018, 6:35 PM
Is the
packetBroadcastChannel
parameter Activity bound or application bound in regards to its lifecycle?
w

withoutclass

08/24/2018, 6:47 PM
application bound, it’s attached to a long running service
It also could be that I don’t quite understand consume
I’m thinking another solution could be to use a pipeline, where a producer takes in a
BroadcastChannel
, consuming each element, and caches them for some delay before producing them.
apparently
use()
will also work which I did not know
openSubscription().use {}
l

louiscad

08/24/2018, 8:56 PM
@withoutclass
openSubscription()
returns a new
ReceiveChannel
which you can
consume
without closing the source
BroadcastChannel
, so it should work for you in place of
use
(and is more explicit regarding the consumption of a channel). What you are looking for though is probably some "debounce". See this gist by @kevinherron (and mind my comment on it to be sure you consume the channel properly 😉 ) https://gist.github.com/kevinherron/5a895911a45eb5752ff247a205d618b7
👍 1
k

kevinherron

08/24/2018, 9:01 PM
@louiscad thanks for the comment. funny, I actually had it in a
consumeEach
originally, but changed it while debugging and never switched back
2 Views