当容量小于消息数量时,Kotlin参与者将陷入僵局

时间:2018-12-10 15:55:09

标签: kotlin

我想与kotlin演员一起对akka演员进行基准测试。在对Kotlin有一些非常基本的了解之后,我尝试使用乒乓进行简单测试,但程序陷入困境。仅当我使容量大小与消息数相同时,它才进展到完成。据我了解,两个参与者都应继续开展工作,而不应依赖能力。

import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.channels.SendChannel
import kotlinx.coroutines.channels.actor
import kotlinx.coroutines.runBlocking

sealed class Message
class Ping(val replyTo: SendChannel<Message>) : Message()
object Pong : Message()

object Start : Message()

fun CoroutineScope.PingActor() = actor<Message>(capacity = 10) {
    for (msg in channel) { 
        when (msg) {
            is Ping ->
                msg.replyTo.send(Pong)
        }
    }
}

fun CoroutineScope.PongActor(pinger: SendChannel<Message>, count: Int, done: CompletableDeferred<Unit>) =
    actor<Message> (capacity = 10){
        var counter = count 

        for (msg in channel) { 
            when (msg) {
                is Start ->
                    for (i in 1..count) {
                        pinger.send(Ping(this.channel))
                    }

                is Pong -> {
                    counter -= 1
                    if (counter == 0) {
                        done.complete(Unit)
                    }
                }
            }

        }
    }

fun main() = runBlocking<Unit> {

    val response = CompletableDeferred<Unit>()
    val pinger = PingActor() 
    val ponger = PongActor(pinger, 100, response) 
    val startTime = System.nanoTime()

    ponger.send(Start)
    response.await()

    println("total time taken is ${System.nanoTime() - startTime}")
    pinger.close() 
    ponger.close()
}

1 个答案:

答案 0 :(得分:0)

  

仅当我使容量大小与消息数相同时,它才进展到完成。

您可以检查50个容量(对于两个演员)实际上是否足够。让我们看看10会发生什么:

  1. pinger收到Start消息
  2. pinger尝试向ponger发送100条消息。发送10个第11个块,直到队列中有更多空间。
  3. ponger处理邮件并发送10条回复。
  4. pinger现在可以再发送10条消息。
  5. ponger尝试处理第11个Ping,但是在发送答复时会阻塞,因为pinger的邮箱中有10条消息。

请注意,pinger无法处理回复,因为它仍在处理Start消息。