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

billybong

12/15/2017, 9:28 AM
Can a coroutine actor send to it’s own channel?
e

elizarov

12/15/2017, 9:33 AM
Yes
m

marstran

12/15/2017, 9:38 AM
What will happen if the channel is full when it tries to send to itself? Will it cause a deadlock?
b

billybong

12/15/2017, 9:51 AM
should it work inside the iteration as well? I’m not receiving any messages I’m sending while iterating over the messages, which makes sense when talking about iterators
Copy code
private val collapsingActor = actor<CollapserAgentMsg<ARGUMENT, RETURN_TYPE>>(CommonPool) {
        val returnChannelsByArg: MutableMap<ARGUMENT, MutableList<Channel<RETURN_TYPE>>> = HashMap()

        for (msg in channel) {
            when (msg) {
                is CollapserAgentMsg.CollapserTrigger<ARGUMENT, RETURN_TYPE> -> {
                    callActionFunction(returnChannelsByArg)
                    returnChannelsByArg.clear()
                }
                is CollapserAgentMsg.CollapserRequest<ARGUMENT, RETURN_TYPE> -> {
                    returnChannelsByArg.compute(msg.arg) { _, v ->
                        val channelList = v ?: mutableListOf()
                        channelList.add(msg.returnChannel)
                        channelList
                    }

                    val nrOfRequests = returnChannelsByArg.values.flatMap { it }.size
                    if (nrOfRequests >= threshold) {
                        channel.send(CollapserAgentMsg.CollapserTrigger<ARGUMENT, RETURN_TYPE>())
                    }
                }
            }
        }
    }
I’m implementing a request collapser where the state is kept inside an actor and triggered after a threshold (time or size). I’d like the actor to trigger itself to run the supplied action when the threshold is met, but the trigger messages is never received.
e

elizarov

12/15/2017, 9:58 AM
Yes. It will deadlock. However, actor can create a child job that sends to its channel. That will work just fine.
💡 1
b

billybong

12/15/2017, 10:03 AM
ok, so just use launc{channel.send(triggerMsg)}?
or a separate actor?
Even though launch seems to work I managed to work around it as I want to perform the action before any more messages comes in. The message sent from the internal launch will of course not be the next message on the channel if external users also send to the actor at the same time.
2 Views