Актеры Kotlin приходят в тупик, когда емкость меньше, чем количество сообщений - PullRequest
0 голосов
/ 10 декабря 2018

Я хотел сравнить актеров akka с kotlin.Имея некоторое базовое понимание 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 голосов
/ 10 декабря 2018

Это прогрессировало до завершения только тогда, когда я установил размер емкости, равный количеству сообщений.

Вы можете проверить, что 50 мощностей (для обоих участников) действительно достаточно.Давайте посмотрим, что происходит с 10:

  1. pinger получает сообщение Start,
  2. pinger пытается отправить 100 сообщений на ponger.10 отправлено, 11-е блоки, пока в очереди не будет больше места.
  3. ponger обрабатывает сообщения и отправляет 10 ответов.
  4. pinger теперь может отправлять еще 10 сообщений.
  5. ponger пытается обработать 11-е Ping, но блокируется при отправке ответа, потому что в почтовом ящике pinger есть 10 сообщений.

Обратите внимание, что pinger никогда не обрабатывает ответы, потому что он все еще обрабатывает Start сообщение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...