1

I want to implement a processing queue in RxJava which downloads some files. The number of files I want to download may be up to around 100.

Everything is developed on Android using RxJava 1.1.1

My current implementation looks something like this:

PublishSubject<URL> publishSubject = PublishSubject.create();
_subject = new SerializedSubject<>(publishSubject);

_subscription = _subject
                .subscribeOn(Schedulers.io())
                .observeOn(Schedulers.io())
                .subscribe(_getObserver());  // Observer

_subject.onBackpressureBuffer(10000, new Action0() {
    @Override
    public void call() {
        Log.d(TAG, "onBackpressureBuffer called");
        return;
    }
});

// download a file
_subject.onNext(aValidURL);

Where _getObserver() returns a new observer object which downloads in the file in the "onNext" method.

However, my problem is that I quickly gets a MissingBackpreasureException, which I do not understand. I tried implementing a backpreasurebuffer, but it just doesn't seem to be called.

What am I doing wrong?

Florian Lemaitre
  • 5,905
  • 2
  • 21
  • 44
Peter Ludvigsen
  • 320
  • 3
  • 12
  • follow the issue in the link https://github.com/ReactiveX/RxJava/issues/2453 – CandleCoder Feb 22 '16 at 10:56
  • @CandleCoder I do not understand. Backpreasure works in other areas of my code. The problem is only present in this specific case, and I suspect it has something to with the fact that I am using a PublishSubject - but that's just a wild guess. The issue in the link is very generic, and not even a real issue as far as I can see. – Peter Ludvigsen Feb 22 '16 at 11:04
  • My understanding is that Subjects inherently do not support backpressure, given the externally-driven behavior they have. Perhaps you're interested in an onBackPressureBuffer call? – Tassos Bassoukos Feb 22 '16 at 11:23
  • @TassosBassoukos That sound correct. But do you have any alternative ideas on how to implement a "queue" where I can continuously add (many) objects to be processed at a later time. – Peter Ludvigsen Feb 22 '16 at 11:27

1 Answers1

2

In RxJava, when you apply an operator, you get a new Observable instance with the modified behavior but the original stays the same. Here, you called onBackpressureBuffer on the _subject but then don't use its result and otherwise the call does nothing. You need to apply that in sequence:

PublishSubject<URL> publishSubject = PublishSubject.create();
_subject = new SerializedSubject<>(publishSubject);

_subscription = _subject
                .onBackpressureBuffer(10000, new Action0() {
                    @Override
                    public void call() {
                        Log.d(TAG, "onBackpressureBuffer called");
                        return;
                    }
                })
                .subscribeOn(Schedulers.io())
                .observeOn(Schedulers.io())
                .subscribe(_getObserver());  // Observer

// download a file
_subject.onNext(aValidURL);
akarnokd
  • 69,132
  • 14
  • 157
  • 192
  • I (strongly) believe I did test that at some point. However, now I have some problems reproducing my exception with your approach. I'll get back to you when I have done some more testing. So far, thank you. – Peter Ludvigsen Feb 22 '16 at 11:38