Akka-Java: невозможно получить сообщение Future в родительском объекте с использованием шаблона канала
Я создаю одного дочернего актера для одного из родителей. Мой детский актер выполняет некоторую бизнес-логику и возвращает значение в Scala Future. Когда я отправляю Future
сообщение для моих родителей, я не могу поймать свое будущее сообщение. Ниже приведен мой код:
Детский актер
public class FetchDevicesIds extends AbstractActor {
private final LoggingAdapter LOG = Logging.getLogger(context().system(), this);
private final ActorRef parent = context().parent();
@Override
public PartialFunction<Object, BoxedUnit> receive() {
return ReceiveBuilder.
match(String.class, msg -> {
final ExecutionContext ec = context().dispatcher();
Future<DevicesIds> future = Futures.future(() -> new DevicesIds(new ArrayList<>()), ec);
future.onFailure(futureFailureHandler(), ec);
System.out.println("************************************ : "+parent);
pipe(future, ec).to(parent);
}).
matchAny(msg -> LOG.info("unknown message: "+ msg)).
build();
}
private OnFailure futureFailureHandler(){
return new OnFailure() {
@Override
public void onFailure(Throwable failure) throws Throwable {
if(failure.getCause() instanceof DevicesNotFound){
self().tell("-----------------", ActorRef.noSender());
}
}
};
}}
Родительский актер
public class NotificationSupervisor extends AbstractActor {
private final LoggingAdapter LOG = Logging.getLogger(context().system(), this);
private final ActorContext context = context();
@Override
public PartialFunction<Object, BoxedUnit> receive() {
return ReceiveBuilder.
match(String.class, msg -> {
ActorRef fetchDeviceIds = context.actorOf(Props.create(FetchDevicesIds.class), "fetch-devices-ids");
fetchDeviceIds.tell("fetch-ids", self());
}).
match(DevicesIds.class, ids -> System.out.println("&&&&&&&&&&&&& I GOT IT")).
matchAny(msg -> LOG.info("unknown message: "+ msg)).
build();
}
бревна
[INFO] [08/21/2016 13:04:10.776] [ActorLifeCycleTest-akka.actor.default-dispatcher-4] [akka://ActorLifeCycleTest/user/notification-supervisor]
Message [java.lang.Integer] from Actor[akka://ActorLifeCycleTest/deadLetters] to TestActor[akka://ActorLifeCycleTest/user/notification-supervisor] was not delivered. [1] dead letters encountered.
This logging can be turned off or adjusted with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letters-during-shutdown'
Обновить
Я пытаюсь отправить tell
родителю, а не будущему, но все еще родитель не получает сообщение. Следующие мои изменения:
parent.tell(23, ActorRef.noSender()); //replace pipe(future, ec).to(parent);
ожидаемый, родитель matchAny(msg -> {System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");LOG.info("unknown message: "+ msg);})
регистр обрабатывать это сообщение. Но ничего не происходит.
Обновление 2
Согласно моему расследованию, когда я закомментирую future.onFailure(futureFailureHandler(), ec);
заявление, parent.tell(23, ActorRef.noSender());
выполнить успешно. До сих пор не понимаю, почему это происходит.
Мои требования: отправлять будущие сообщения родительскому субъекту и обрабатывать будущие ошибки для обеспечения отказоустойчивости в системе акторов akka.
1 ответ
Я все еще не понимаю, какая именно проблема с приведенным выше кодом и как я могу решить эту проблему. Но нашел другой альтернативный способ для выполнения akka pipe
шаблон с java
, Ниже приведен код:
public class FetchDevicesIds extends AbstractActor {
private final LoggingAdapter LOG = Logging.getLogger(context().system(), this);
private DeviceService deviceService = new DeviceServiceImpl();
@Override
public PartialFunction<Object, BoxedUnit> receive() {
return ReceiveBuilder.
match(String.class, msg -> {
final ExecutionContext ec = context().system().dispatcher();
CompletableFuture<DevicesIds> devicesIds = deviceService.getAllDevicesIds();
pipe(devicesIds, ec).to(context().parent());
}).
matchAny(msg -> LOG.info("unknown message: "+ msg)).
build();
}}
Мы можем напрямую использовать Java 8 CompletableFuture
с использованием Акки import static akka.pattern.PatternsCS.pipe;
шаблон. Akka PatternsCS
для ручки Java 8 CompletableFuture
,
Примечание: использовать context().parent()
в обработчике сообщений вместо создания родительского экземпляра в актере, как private final ActorRef parent = context().parent();
, Я до сих пор не понимаю, почему это происходит, но некоторое время с родительской переменной экземпляра, pipe
шаблон не работает.