akka 2.2.0 Scala 2.11 "сообщение не доставлено" - если только не используется Thread.sleep(50)

Я новичок в Scala и Akka, но у меня простой сценарий... Я пытаюсь получить список URL-адресов, отправляя каждый URL-адрес в виде сообщения новому субъекту, который отправит запрос http GET. Имея только список из 16 URL-адресов, я получаю около 40-65% успехов, остальные получают сообщение "сообщение не доставлено". Однако, если я добавлю Thread.sleep(50) перед созданием актера (ов), я не получу промахи. Примечание: HTTP Get использует класс java, а не класс scala, который может или не может быть фактором. См. Пример кода ниже... Я знаю, что Akka не гарантирует сообщения, но этот показатель успеха выглядит неправильно, я должен делать это неправильно. Спасибо за любые указатели.

  def ParallelTest(urls: List[String]): String =   {
     val system = ActorSystem("HelloSystem")

     var cnt: Int = 0
     for (item <- urls){
       Thread.sleep(50)
       createActor(system, "helloactor" + cnt, item)
       cnt += 1
       /*
       historical example
       helloActor ! "hello"
       helloActor ! "hello"
       helloActor ! "Buenos dias"
       */
      }
     system.shutdown

     println("parallel done");
     "done"   
   }

  def createActor(actorSystem: ActorSystem, actorName: String, urlItem: String) = {
    val helloActor = actorSystem.actorOf(Props[HelloActor], name = actorName)
    helloActor ! UrlTransport(urlItem)
  }

1 ответ

Решение

Вы можете подумать о том, чтобы сделать что-то подобное, имея менеджера, чтобы актеры знали, когда они закончили.

class HelloManager(urls: List[String]) extends Actor {

    var completed = 0
    def remaining = urls.size - completed

    def receive: Receive = {
        case StartSystem => startRequests
        case RequestComplete => handleComplete

    }

    def startRequests(): Unit = {
        for ((url, i) <- urls.zipWithIndex) {
            val helloActor = context.actorOf(Props[HelloActor], name = s"helloActor$i")
            helloActor ! UrlTransport(url)
        }
    }  

    def handleComplete(): Unit = {
        completed += 1
        if (remaining == 0) 
            // do something like
            // context.stop(self)
    }
}

Тогда вам просто нужен HelloActor, чтобы сделать sender ! RequestComplete когда это сделано со своей работой.

Другие вопросы по тегам