Актер Скала Акка - встречаются мертвые буквы - PullRequest
0 голосов
/ 08 ноября 2018

Я использую Scala с актерами Акки.Я знаю, что у актера есть почтовый ящик.Так что любая связь с актером сериализуется.У меня есть актер, который выполняет определенную работу - скажем, он загружает изображение.

class DownloadImageActor(implicit val injector: Injector) extends Actor with Injectable {
  val imageDownloadService = inject[ImageDownloadService]
  implicit val ec = inject[ExecutionContext]

  override def receive: Receive = {
    case DownloadImage(jobId, imageUrl) =>
      imageDownloadService.downloadImage(imageUrl).onComplete {
        case Success(image) =>
          sender() ! ImageDownloadSuccess(imageUrl, image, jobId)
        case Failure(e) =>
          sender() ! ImageDownloadFail(imageUrl, e, jobId)
      }
  }
}

Как видите, актер загружает изображение в асинхронном режиме.imageDownloadService.downloadImage возвращает Future, по завершении которого отправителю отправляется сообщение.Теперь я получаю сообщение dead letters encountered.

Где я ошибся?



РЕДАКТИРОВАТЬ # 1

Родительский актер, который отправляет сообщение актеру загрузки

class ParentActor(implicit val injector : Injector) extends Actor with Injectable {

  val downloadImageActor = inject[ActorRef](identified by "ImageDownloadActor")


  override def receive: Receive = {
    case DownloadImages(urls, _id) => urls.foreach(url =>
      downloadImageActor ! DownloadImage(id, imageUrl = url)
    )
    case ImageDownloadSuccess(image : Image) =>
  }
}

1 Ответ

0 голосов
/ 08 ноября 2018

Не знаю, есть ли другая проблема, но метод, который вы используете sender в Future, неверен, вам нужно присвоить его новой переменной, а затем объединить обратный вызов onComplete, который образует замыкание, которое будет не может быть переопределено другим дескриптором актера.

В вашем коде нужно добавить строку A и заменить lineB, lineC на lineD, lineE. Или вы можете захотеть взглянуть на pipeTo функцию Future.

class DownloadImageActor(implicit val injector : Injector)  extends Actor with Injectable{
  val imageDownloadService = inject[ImageDownloadService]
  implicit val ec = inject[ExecutionContext]

  override def receive: Receive = {
    case DownloadImage(jobId, imageUrl) => 
      val client = sender // lineA
      imageDownloadService.downloadImage(imageUrl).onComplete {
      //case Success(image) => sender() !  ImageDownloadSuccess(imageUrl, image, jobId) // lineB
      //case Failure(e) => sender() !  ImageDownloadFail(imageUrl,e, jobId) // lineC
      case Success(image) => client !  ImageDownloadSuccess(imageUrl, image, jobId) // lineD
      case Failure(e) => client !  ImageDownloadFail(imageUrl,e, jobId) // lineE
    }
  }
}
...