Как использовать фьючерсы с Akka для асинхронных результатов

Я пытаюсь одновременно писать в несколько файлов, используя инфраструктуру Akka. Сначала я создал класс с именем MyWriter, который записывает в файл, а затем, используя фьючерсы, я дважды вызываю объект, прыгая, что для меня будут созданы 2 файла, но когда я отслеживаю выполнения программы, она сначала заполняет первый файл, а затем второй (блокируя/синхронно).

В: как я могу запустить приведенный ниже код (без блокировки/асинхронно)

import akka.actor._
import akka.dispatch._
import akka.pattern.ask
import akka.util.Timeout

import scala.concurrent.Await
import scala.concurrent.duration._
import scala.concurrent.Future
import scala.concurrent.{ ExecutionContext, Promise }
import ExecutionContext.Implicits.global

class my_controler {

}

object Main extends App {

  val system = ActorSystem("HelloSystem")
  val myobj = system.actorOf(Props(new MyWriter), name = "myobj")
  implicit val timeout = Timeout(50 seconds)
  val future2 = Future { myobj ! save("lots of conentet") }
  val future1 = Future { myobj ! save("event more lots of conentet") }

}

код MyWriter:

case class save(startval: String)

class MyWriter extends Actor {
  def receive = {
    case save(startval) => save_to_file(startval)
  }

есть идеи, почему код не выполняется одновременно?


person CruncherBigData    schedule 19.05.2013    source источник
comment
Как было определено save?   -  person om-nom-nom    schedule 19.05.2013
comment
хорошо, позвольте мне отредактировать мой вопрос, чтобы добавить это   -  person CruncherBigData    schedule 19.05.2013
comment
Помните, что жесткие диски не любят параллельный доступ. Они тормозят - много. Поэтому не записывайте файлы параллельно, если они находятся на одном жестком диске. Также, как уже упоминалось, не переносите общение с актером на будущее.   -  person SpiderPig    schedule 19.05.2013


Ответы (1)


Почему вы оборачиваете вызов ? дополнительным Future? Ask (?) в любом случае возвращает Future, так что здесь вы оборачиваете Future вокруг другого Future, и я не уверен, что вы хотели это сделать.

Вторая проблема, которую я вижу, заключается в том, что вы отправляете два сообщения одному и тому же экземпляру актора и ожидаете, что они будут выполняться параллельно. Экземпляр субъекта последовательно обрабатывает свой почтовый ящик. Если вы хотите выполнять параллельную обработку, для этого вам понадобятся два экземпляра вашего FileWriter актора. Если это все, что вы хотите сделать, просто запустите другой экземпляр FileWriter и отправьте ему второе сообщение.

person cmbaxter    schedule 19.05.2013
comment
вы абсолютно правы, я создавал экземпляр одного и того же объекта, теперь, когда я создал два разных объекта, он работал параллельно. Большое спасибо. - person CruncherBigData; 19.05.2013
comment
Еще один вопрос: что, если я хочу запустить, скажем, 100 экземпляров fileWriter , как лучше всего это сделать? - person CruncherBigData; 19.05.2013
comment
Для этого сценария я бы предложил использовать маршрутизатор в пуле, а затем что-то вроде стратегии циклического перебора или наименьшего почтового ящика. Пусть акторы живут долго и сидят за роутером, который будет раздавать им сообщения. Ознакомьтесь с документацией на Routers, чтобы узнать, как это сделать, но с точки создания это будет выглядеть так: system.actorOf(Props[MyWriter].withRouter(RoundRobinRouter(100)), "filewriter"). Документы: doc.akka.io/docs/akka/2.1. 4/скала/роутинг.html - person cmbaxter; 19.05.2013