Акка Актеры: нужен пример, чтобы понять некоторые основы
Я возился с Аккой и нуждаюсь в некотором совете, как реализовать что-то конкретное, что я имею в виду. Я хочу иметь актера, который могу отправить сообщение DownloadFile(URI, File)
и загрузить его. Поскольку это может быть параллельно, я не хочу загружать файл после файла, но имею ограничение одновременных загрузок.
Каким образом можно моделировать что-то подобное с Akka? Другие вещи, которые приходят на ум: что произойдет, если какой-нибудь из "рабочего" актера умрет по какой-то причине? Как повторить загрузку? И т.д. и т.д.
Я знаю, что это очень большой вопрос, но я надеюсь, что кто-то найдет время, чтобы ответить на него! Спасибо!
Ответы
Ответ 1
Сделайте это выстрелом; он создает три, но вы можете настроить его для создания столько, сколько хотите - загрузчиков, так что три запроса на скачивание могут обрабатываться одновременно.
sealed trait DownloaderMessage
case class DownloadFile(uri: URI, file: File) extends DownloaderMessage
object Downloader {
val dispatcher = Dispatchers.newExecutorBasedEventDrivenWorkStealingDispatcher("pool").build
}
class Downloader extends Actor {
self.lifeCycle = Permanent
self.dispatcher = Downloader.dispatcher
def receive = {
case DownloadFile(uri, file) =>
// do the download
}
}
trait CyclicLoadBalancing extends LoadBalancer { this: Actor =>
val downloaders: List[ActorRef]
val seq = new CyclicIterator[ActorRef](downloaders)
}
trait DownloadManager extends Actor {
self.lifeCycle = Permanent
self.faultHandler = OneForOneStrategy(List(classOf[Exception]), 5, 5000)
val downloaders: List[ActorRef]
override def preStart = downloaders foreach { self.startLink(_) }
override def postStop = self.shutdownLinkedActors()
}
class DownloadService extends DownloadManager with CyclicLoadBalancing {
val downloaders = List.fill(3)(Actor.actorOf[Downloader])
}
Ответ 2
Создайте класс DownloadActor, который управляет загрузками,
У всех DownloadActors есть один и тот же Диспетчер,
Настройте Диспетчер в соответствии с вашими потребностями (максимальное количество потоков, размер очереди и т.д.),
Связать ли все DownloadActors с тем же Супервизором,
Настройте Супервизор в соответствии с вашими потребностями (возможно, OneForOneStrategy),
Создайте новый DownloadActor для каждой новой загрузки или используйте LoadBalancer с соответствующим InfiniteIterator для распространения загрузок в DownloadActors.
Если вы используете AsycHttpClient для загрузки файлов, он поддерживает download-resume.