Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

retryWhen method signature for with Completable and Single #5135

Closed
jeremy303 opened this issue Feb 24, 2017 · 13 comments
Closed

retryWhen method signature for with Completable and Single #5135

jeremy303 opened this issue Feb 24, 2017 · 13 comments

Comments

@jeremy303
Copy link

jeremy303 commented Feb 24, 2017

When I attempt to use retryWhen to delay a retry with Completable or Single I receive an incompatible types error, as demonstrated in the following code:

        Completable.error(new RuntimeException())
                .retryWhen(new Function<Flowable<Throwable>, Publisher<Object>>() {
                    @Override
                    public Publisher<Object> apply(@io.reactivex.annotations.NonNull Flowable<Throwable> source) throws Exception {
                        return source.delay(5, TimeUnit.SECONDS); // <- Incompatible type error
                    }
                });
        
        Single.error(new RuntimeException())
                .retryWhen(new Function<Flowable<Throwable>, Publisher<Object>>() {
                    @Override
                    public Publisher<Object> apply(@io.reactivex.annotations.NonNull Flowable<Throwable> source) throws Exception {
                        return source.delay(5, TimeUnit.SECONDS); // <- Incompatible type error
                    }
                });

However, there are no issues with Observable or Flowable:

        Observable.error(new RuntimeException())
                .retryWhen(new Function<Observable<Throwable>, ObservableSource<?>>() {
                    @Override
                    public ObservableSource<?> apply(@io.reactivex.annotations.NonNull Observable<Throwable> source) throws Exception {
                        return source.delay(5, TimeUnit.SECONDS);
                    }
                });
        Flowable.error(new RuntimeException())
                .retryWhen(new Function<Flowable<Throwable>, Publisher<?>>() {
                    @Override
                    public Publisher<?> apply(@io.reactivex.annotations.NonNull Flowable<Throwable> source) throws Exception {
                        return source.delay(5, TimeUnit.SECONDS);
                    }
                });

Looks like there is an issue with the return types for apply?

@jeremy303 jeremy303 changed the title retr retryWhen method signature for with Completable and Single Feb 24, 2017
@jeremy303
Copy link
Author

@akarnokd Sorry, I accidentally submitted the issue without my description. Now fixed. This isn't a crosspost, but appears to be a bug.

@akarnokd
Copy link
Member

You have the wrong return type argument in the first case. Either change it to ? or Throwable.

@jeremy303
Copy link
Author

@akarnokd Aren't the Completable runwith Function argument and return types incompatible?

public final Completable retryWhen(Function<? super Flowable<Throwable>, ? extends Publisher<Object>> handler) 

So the following retryWith lambda:

    Completable.error(new RuntimeException())
            .retryWhen(throwableFlowable -> throwableFlowable.delay(5, TimeUnit.SECONDS); 

produces the error:

Bad return type in lambda expression: Flowable<Throwable> cannot be converted to Publisher<Object>

@akarnokd
Copy link
Member

Thanks, I see he issue now. Indeed, the Completable and Single signature for retryWhen is different from the others. repeatWhen is also off. Would you like to submit a PR?

@akarnokd akarnokd added Bug and removed Question labels Feb 24, 2017
@jeremy303
Copy link
Author

jeremy303 commented Feb 24, 2017

Sure, I can do that.

Question: Should the function return type be Publisher<?> or CompletableSource<?> / SingleSource<?> ? Flowable and Observable differ in this regard.

@akarnokd
Copy link
Member

I'd like to encourage you to think about that a bit.

@akarnokd
Copy link
Member

Two hints:

  • you'd want to retry multiple times
  • you'd want to avoid ClassCastException on existing operator users

@akarnokd
Copy link
Member

Closing via #5136.

@feinstein
Copy link

@akarnokd I tried to use:

.retryWhen(errors -> errors.flatMap(error -> Observable.timer(30, TimeUnit.SECONDS)))

On a Transformer for a Single and I am getting this error:

error: incompatible types: cannot infer type-variable(s) R (argument mismatch; bad return type in lambda expression Observable cannot be converted to Publisher) where R,T are type-variables: R extends Object declared in method flatMap(Function>) T extends Object declared in class Flowable

And the squiggly lines below error -> Observable.timer(30, TimeUnit.SECONDS) say:

no instance(s) of type variable(s) R exist so that Observable conforms to Publisher

What am I doing wrong? Is this bug fixed?

@feinstein
Copy link

Using Flowable.timer instead fixes this, is this something only related to Single? Because this tutorial uses Observable.timer with no issues.

@akarnokd
Copy link
Member

What am I doing wrong?

Please check the signatures of operators so that you are using the right types: https://github.com/ReactiveX/RxJava#base-class-vs-base-type

Because this tutorial uses Observable.timer with no issues.

That tutorial predates RxJava 2.

is this something only related to Single

retryWhen and repeatWhen use Publisher as the redo signal by design so that we can leverage backpressure to only ask for one such redo signal at a time. With Observable, there is a chance a handler would simply dump a lot of signals at once and the operators may behaved unexpectedly.

@akarnokd
Copy link
Member

@feinstein
Copy link

I thought about posting here the stackoverflow link, but many people just ignore links, I am glad you aren't one of those. Thank you very much for the explanation!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants