Акка объединяет несколько списков фьючерсов без блокировки - PullRequest
0 голосов
/ 11 января 2012

Этот вопрос, вероятно, относительно базовый для того, кто знаком с akka Futures, поэтому, пожалуйста, потерпите меня.

Предполагая, что у меня есть иерархия актеров akka для следующей структуры:

BigBoss                 (one)
|___ExecutiveActor      (one)
    |___ManagerActor    (many)
        |___WorkerActor (many)

И предполагая, что каждый не-BigBoss имеет внутреннее состояние в оболочке Status.

Если BigBoss хочет получить List<Status> от всех потомков, я могу видеть, что это метод:

// inside BigBoss getAllStatuses
Future<Object> futureStatuses = executive.ask("status", 5000);
List<Status> = (List<Status>)Await.(futureStatuses, timeout);

И после того, как исходное сообщение распространяется вплоть до Worker, я вижу, что Worker отвечает на Manager с помощью:

getSender().tell(myStatus);

Manager получит много таких сообщений и захочет их поместить всписок для руководителя как список фьючерсов - ответ выше:

// inside Manager getAllStatuses
List<Future<Object>> statuses =...
for(Worker w : workers) {
   Future<Object> status = w.ask("status", 5000);
   statuses.add(status);
}

Future<List<Object>> futureStatuses = sequence(statuses, ...);
getSender().tell(futureStatuses);

Приведенная выше последовательность сначала преобразует фьючерс в Future<List<Object>> (в котором действительно есть статусы)

Так что это то, где это начинает становиться немного волосатым для меня.

ExecutiveActor сделал это:

for(Manager m : managers) {
   Future<Object> status = m.ask("status", 5000);
   // the above Future would be a Future<Future<List<Object>>
}

Итак, наконец - мои вопросы -

  1. Как дo Я уменьшаю Future<Future<List<Object>> до Future<List<Object>> без блокировки до тех пор, пока BigBoss наконец не вызовет Await?

  2. Есть ли способ сохранить тип Status во всем этом, а не использовать Object?Я знаю, что UntypedActor не может отправить явно напечатанный ответ, но, возможно, есть более понятный способ выразить это?

  3. Есть ли более элегантный подход к этому полностью, о котором я не думаю?Я слишком рано использовал Sequence или вообще не использовал?

Я (очевидно) использую Java - и предпочел бы не использовать TypedActors, но хотел бы получить все отзывы!

Большое спасибо за потраченное время-

1 Ответ

1 голос
/ 11 января 2012

Как то так?

final ActorRef cacheSender = getSender();
Future<List<Object>> futureStatuses = sequence(statuses, ...);
futureStatuses.onComplete( new Procedure2<Throwable, List<Object>>() {
  public void apply(Throwable t, Object r) {
    if(t != null) cacheSender.tell("ohnoes");
    else cacheSender.tell(r);
  }
});
...