Akka “阿克卡”;“尽最大努力重试”;使用RxJava

Akka “阿克卡”;“尽最大努力重试”;使用RxJava,akka,rx-java,Akka,Rx Java,我很好奇使用RxJava在Akka中实现最大努力重试,而不需要持久参与者。我们的想法是使用Rx的retry方法不断询问,直到收到目标参与者的响应 这方面的其他例子很难找到。有没有任何阿克卡大师可以验证这个实现,或者指出一个更好的解决方案 例如: public class RxWithAkka { private final Logger LOGGER = LoggerFactory.getLogger(getClass()); public static final Time

我很好奇使用RxJava在Akka中实现最大努力重试,而不需要持久参与者。我们的想法是使用Rx的
retry
方法不断询问,直到收到目标参与者的响应

这方面的其他例子很难找到。有没有任何阿克卡大师可以验证这个实现,或者指出一个更好的解决方案

例如:

public class RxWithAkka {

    private final Logger LOGGER = LoggerFactory.getLogger(getClass());

    public static final Timeout TIMEOUT = Timeout.apply(10, TimeUnit.MILLISECONDS);
    private final ActorRef actor;
    private final ActorSystem actorSystem;

    public RxWithAkka(ActorSystem actorSystem) {
        this.actorSystem = actorSystem;
        this.actor = actorSystem.actorOf(Props.create(MyActor.class));
    }

    public Observable<Object> ping() {
        return createObservable()
                .doOnError(t -> LOGGER.warn(t.getMessage()))
                .retry();
    }

    Observable<Object> createObservable() {
        return Observable.create(subscriber -> {
            LOGGER.info("Send ping");
            Patterns.ask(actor, "ping", TIMEOUT)
                    .onComplete(new OnComplete<Object>() {
                        @Override
                        public void onComplete(Throwable failure, Object success) throws Throwable {
                            if (success != null) {
                                subscriber.onNext(success);
                                subscriber.onCompleted();
                            } else {
                                subscriber.onError(failure);
                            }
                        }
                    }, actorSystem.dispatcher());
        });
    }
}
测试:


在RxJava中,您可以将
timeout
操作符与
retry

结合使用,这可能很明显,但我还是要说:没有持久性,它实际上不会至少出现一次,而是“尽最大努力重试”。不要说这是不好的,您的用例可能完全可以做到这一点,只是尝试保持术语的正确性。
public class MyActor extends UntypedActor {

        private int counter = 0;

        @Override
        public void onReceive(Object message) throws Exception {
            switch (counter++) {
                case 0:
                    // ignore message
                    break;
                case 1:
                    // timeout
                    Thread.sleep(200);
                    break;
                default:
                    getSender().tell("pong", getSelf());
            }
        }
    }
}
public class RxWithAkkaTest {

    @Test
    public void testIt() throws Exception {
        ActorSystem system = ActorSystem.create("system");
        RxWithAkka example = new RxWithAkka(system);
        String res = (String) example.ping().toBlocking().first();
        assertThat(res).isEqualTo("pong");
    }
}