Wanted behavior:
subject = BehaviorSubject.create(1);
subject.subscribe(number -> print(number), error -> print(error));
subject.onNext(2);
subject.onNext(3);
subject.onError(new RuntimeException("I'm an error"));
subject.onNext(4);
subject.onNext(5);
With this output:
1
2
3
I'm an error
4
5
My problem is that onNext after onError isn't working (and this is intended, following RxJava rules), but I'll need subject to be resilient to errors, while also passing them down the stream (to show the user some feedback).
Is there a way to do this?
If you want onError and onComplete to be disregarded there is the RxRelay library.
Description:
Subjects are useful to bridge the gap between non-Rx APIs. However, they are stateful in a damaging way: when they receive an onComplete or onError they no longer become usable for moving data. This is the observable contract and sometimes it is the desired behavior. Most times it is not.
Relays are simply Subjects without the aforementioned property. They allow you to bridge non-Rx APIs into Rx easily, and without the worry of accidentally triggering a terminal state.
Try to use .onErrorReturn() just before subscription
Related
In rxJava 1 there was Scheduler.immediate() which let you schedule work on the current thread. In rxJava 3 I can no longer find this scheduler.
Does anyone know what the replacement for Scheduler.immediate() is in rxJava 3?
My use case:
I have a client-side API which I use to subscribe to an infinite stream of events (e.g. a news feed) from a remote server. The API notifies me of events via a callback which I register:
Observable.create(emitter -> apiClient.registerCallback(event -> emitter.onNext(event)))
.observeOn(Schedulers.immediate()) // I'd like downstream operators to run on current thread
.map(myFunc);
However, the API calls my callback from a different thread. I wish to run downstream computations like myFunc on the current thread (the one that created the Observable) so as not to block the API's thread.
AFAIK, in RxJava 3 you can employ ImmediateThinScheduler to obtain the same effect.
Although it's kept in the internal package, you can use it.
The API is so simple you can actually create one yourself if you don't want to depend on their internal package.
I'm trying to repeat a subscribtion on a Flux like this:
DirectProcessor<String> stringDirectProcessor = DirectProcessor.create();
stringDirectProcessor
.repeat(3)
.subscribe(item -> System.out.println(item));
stringDirectProcessor.onNext("one");
stringDirectProcessor.onNext("two");
stringDirectProcessor.onNext("three");
stringDirectProcessor.onComplete();
My expectation would be to see this output:
one
two
three
one
two
three
one
two
three
one
two
three
But I only get
one
two
three
However if I use Flux.just() instead of DirectProcessor I do get the expected output.
What's wrong?
This is the expected behavior of the DirectProcessor. I just read through the documentation and found the following regarding the DirectProcessor:
Once the Processor has terminated (usually through its sink’s error(Throwable) or complete() methods being called), it lets more subscribers subscribe but replays the termination signal to them immediately.
So, since, repeat simply resubscribes, the onComplete handler will be called on them immediately. Are you sure you need the DirectProcessor?
EDIT: This behavior is also documented here
Note: If there are no Subscribers, upstream items are dropped and only the terminal events are retained. A terminated DirectProcessor will emit the terminal signal to late subscribers.
Here is the problem,
I have a network request which downloads some information. However, it is essential that this request is called only once during some period of time ( you will get the idea later on ) and all subscribers get the same result. My first thought was to use the share() operator, so it would multicast the result while keeping a single request source. But I am not sure what is going to happen if I try to subscribe to it again after the share operator already disposed the resources due to refCount dropping to 0.
The thing I am trying to accomplish here is that every request that I make, is dependent on the current state of information stored and those requests update this information. Once I make the first request, I need to keep a reference to it and inform every subscriber that subscribes until the time of request completion. After the request is finished, all subscribers gets their notification and unsubscribes... However, if there is a new subscription after the disposal I need it to repeat the request, thus resubscribing to the original source observable that was modified using share
Is something like this possible with simple share operator, or do I need to create a subject and control the emissions manually ?
There is a nice library RxReplayingShare, which I think makes exactly, what you are trying to achieve.
It passes the same result to all Subscriber's, when at least one is subscribed. When there are no subscribers anymore, the Observable completes. When subscribing again, the original Observable is called.
The RxMarble shows it better than the description.
I have an Observable that go to database and query for some information. I don't want my observable executes longer than 5 seconds, thus I use:
myObservable.timeout(5,second);
Then I want to handle the error notification also, thus I use:
myObservable.timeout(5,second).onError(return empty result);
Then I wonder for what will happen to the code in myObservable that is used to do database query. Will it also be terminated, or it will continue to run ? (which happens to Java native Future.get(timeLimit))
Let's take an example :
Observable.interval(1, TimeUnit.SECONDS)
.timeout(10, TimeUnit.MICROSECONDS)
.onErrorReturn(e -> -1L)
.subscribe(System.out::println,
Throwable::printStackTrace,
() -> System.err.println("completed"));
the timeout operator will emit an error. But precedent operators won't be notifier of this error.
The operator onErrorReturn will transform your error to an event and then will complete your stream (and mark it as finished) and then your source observable will be unsubscribe.
This unsubscription part will run some code that, depending of how your source observable is written, that may stop your request, or just do nothing, or free some resources.
In your case, it may call the cancel method on your Future (according to the Subscriptions class)
What are all the similarities and diferences between them, It looks like Java Parallel Stream has some of the element available in RXJava, is that right?
Rx is an API for creating and processing observable sequences. The Streams API is for processing iterable sequences. Rx sequences are push-based; you are notified when an element is available. A Stream is pull-based; it "asks" for items to process. They may appear similar because they both support similar operators/transforms, but the mechanics are essentially opposites of each other.
Stream is pull based. Personally I feel it is Oracle's answer to C# IEnumerable<>, LINQ and their related extension methods.
RxJava is push based, which I am not sure whether it is .NET's reactive extensions released first or Rx project goes live first.
Conceptually they are totally different and their applications are also different.
If you are implementing a text searching program on a text file that's so large that you can't load everything and fit into memory, you would probably want to use Stream since you can easily determine if you have next lines available by keeping track of your iterator, and scan line by line.
Another application of Stream would be parallel calculations on a collection of data. Nowadays every machine has multiple cores but you won't know easily exactly how many cores your client machine are available. It would be hard to pre-configure the number of threads to operate. So we use parallel stream and let the JVM to determine that for us (supposed to be more optimal).
On the other hand, if you are implementing a program that takes an user input string and searches for available videos on the web, you would use RX since you won't even know when the program will start getting any results (or receive an error of network timeout). To make your program responsive you have to let the program "subscribe" for network updates and complete signals.
Another common application of Rx is on GUI to "detect user finished input" without requiring the user to click a button to confirm. For example you want to have a text field whenever the user stops typing you start searching without waiting a "Search button" click. In this case you use Rx to create an observable on "KeyEvent" and "throttle" (e.g. at 500ms), so that whenever he stopped typing for 500ms you receive an onNext() to "start searching".
There is also a difference in threading.
Stream#parallel splits the sequence into parts, and each part is processed in the separate thread.
Observable#subscribeOn and Observable#observeOn are both 'move' execution to another thread, but don't split the sequence.
In other words, for any particular processing stage:
parallel Stream may process different elements on different threads
Observable will use one thread for the stage
E. g. we have Observable/Stream of many elements and two processing stages:
Observable.create(...)
.observeOn(Schedulers.io())
.map(x -> stage1(x))
.observeOn(Schedulers.io())
.map(y -> stage2(y))
.forEach(...);
Stream.generate(...)
.parallel()
.map(x -> stage1(x))
.map(y -> stage2(y))
.forEach(...);
Observable will use no more than 2 additional threads (one per stage), so no two x'es or y's are accessed by different threads. Stream, on the countrary, may span each stage across several threads.