У меня есть актер, который выглядит так. Когда я ожидаю. Исследуя исключение, я получаю исключение IllegalState, несмотря на то, что я использую recoverWith. Я вижу, что система работает, поэтому я знаю, что это правильно составлено. Также это сложнее в java, чем в scala!
Что с этим? Я думал, что он должен был больше не возвращать исключение.
public void onReceive(final Object message) throws Exception {
if (message instanceof MyMessage) {
final String key = ((messages.MyMessage) message).getKey();
F.Promise<T> promise = asyncService.get(key);
promise.wrapped().recoverWith(new Recover<Future<T>>() {
@Override
public Future<T> recover(Throwable failure) throws Throwable {
if (failure instanceof IllegalStateException) {
Future future = Patterns.ask(serviceActor, key, timeout);
future.onSuccess(new OnSuccess() {
@Override
public void onSuccess(Object result) throws Throwable {
System.out.println("Here");
}
}, context().dispatcher());
return future;
} else {
throw failure; //there is actually an issue.
}
}
}, context().system().dispatcher()); //also tried context().dispatcher()
Patterns.pipe(promise.wrapped(), context().dispatcher()).to(sender());
} else {
log.warning("Unexpected message type - Cache actor ignoring message: " + message.toString());
unhandled(message);
}
}
Если я делаю varender в исходном контексте и заменяю System.out.println ответом отправителю, он работает.
Я раньше не работал с Akka на Java, но думаю, что ваша проблема в этой строке:
promise.wrapped().recoverWith(new Recover<Future<T>>() {
Вы получаете будущее scala, и вы вызываете recoverWith
. Но это не меняет первоначального будущего будущего обещания! Вместо этого он создает новое будущее. Поэтому я бы рекомендовал изменить код следующим образом. Вы назначаете это новое будущее переменной и передаете это новое вашему отправителю:
Future<T> recovered = promise.wrapped().recoverWith(new Recover<Future<T>>() {
...
Patterns.pipe(recovered, context().dispatcher()).to(sender());