Reactive Extensions (Rx) in Scala - execute a method after a given interval - scala

Since I'm quite new to Reactive Extensions, I was curious about the following things.
By using Rx in Scala, I want to be able to call a method that retrieves content from an API every second.
So far, I've taken a look at the creational operators used within Rx such as Interval, Timer and so forth. But unfortunately, I cannot come up with the correct solution.
Does anyone have some experience with this, and preferably code examples to share?
Thanks in advance!

Using RxJava:
Observable.interval(1, TimeUnit.SECONDS)
.map(interval -> getSuffFromApi()) //Upto here, we have an observable the spits out the data from the API every second
.subscribe(response-> System.out.println(response)); //Now we just subscribe to it
Or:
Observable.interval(1, TimeUnit.SECONDS) //Emit every second
.subscribe(interval ->System.out.println(getSuffFromApi())) //onNext - get the data from the API and print it

Related

using transformToUni

being relatively new to mutiny I am having a little difucauly wrapping my head around the following:
given the following working code:
public Uni<Long> getCounterValue() {
return this.vertx.sharedData().getCounter(COUNTER_NAME).onItem().transformToUni(counter->counter.get());
}
I simply want to return a Uni where the Long is a current state of a vert.x shared counter.
what is hard for me is that counter.get() actually already returns a Uni so I feel like I am doing a transformToUni on something that already has the return time I need.
I hope I explained myself. like I said, the code works but its hard for me to get the why... maybe there's also another way, more self explanatory, to achieve this?
(BTW, I looked at the guides but still I am confused)
your comments are appreciated.
thanks
I think the explanation is that you need a new Uni that's aware of the event emitted by getCounter and that will call counter.get(). Or, in general, a new Uni that knows what to do with the result of the previous one and makes sure that everything happens in the right order at subscription.
Let's take a simpler example, we have three Uni:
Uni<?> first = Uni.createFrom,().item(1).invoke(System.out::print);
Uni<?> second = Uni.createFrom().item(2).invoke(System.out::print);
Uni<?> third = first.chain(() -> second);
If you subscribe first, it will print 1.
If you subscribe second, it will print 2.
If you subscribe third, it will print 12.
These are three different Uni, emitting different events at different times.
What you are suggesting is to return second when transformToUni (or chain) is called to create third. But, in that case, the result would be different from what we want.

reactive 4.2.0 net Subject<T> ReplaySubject<T>

I am using ReplaySubject as a pipe when I feed the Observer with OnNext messages and then I subscribe to the message in another part of the code.
I tried ISubject first, by using Subject.Create(observer:, observable:) but this seems to do nothing, or in other words, the Observer is a sink that goes nowhere. Is there some code that will make the Subject do something pipe-like. For example, I want to inject onNext messages with a integral countN and I want the observable to broadcast N-many 0.00E0(s) in sequence.
UPDATE:
It seems I need to implement the ISubject interface. Is there source code for a simple implementation that functions the same as ReplaySubject, with simple, proper memory handling of buffer size and Observer collection and Disposable return object.
Ok, so you use
new Subject<Int32>()
to get a subject that is a pipe-line.
Someone care to explain what Subject.Create does?
Can you inherit from Subject or ReplaySubject? Should you be able to?

what happen if a flux/mono/Observable never be subscribed

public void test(){
Mono<String> mono = Mono.just("aaa")
FLux<String> flux = Flux.fromArray()
Observable<String> observable = Observable.from(...)
}
what happened test method has been executed?
all the three object will be collected by GC?
if there's some operation, the operation will never be executed?
if the question above is no, what would happened?
To better understand how Flux and Mono is working, you can imagine them as pipes. When you write code - you are not doing operations on your data, but you only describe what should happen to data when pipe will be complete. To make the pipe complete - you need to subscribe to it (that's the end of the pipe).
For example this code:
Mono sampleMono = Mono.just(1)
.map(Integer::toString)
.doOnNext(System.out::println)
In this code, you only tell, what should be done when someone subscribe to sampleMono. when someone do that - then 1 will be emitted, mapped to String and printed to console. But it will happen only after subscribe.
It's something like water pipeline - you can get cold water from well and install water heater. But you newer get warm water until you use shower or sink (you need to subscribe for warm water :) ).
Mono and Flux are lazy - so it will emit only when someone subscribe. Of course - all of the code lines were executed, but they are responsible for creating "pipeline", and until you subscribe - they remain unused. But maybe java with optimizers will do the thing, and these lines will be removed from machine code at all.

flatMap() vs subscribe() in Spring webflux

I am a newbie to Spring WebFlux and trying to convert my spring MVC application to webflux. I return a Mono mono from my service :
List<Store> stores = new ArrayList();
When I do:
mono.subscribe(stores::addAll);
dataexchange.put("stores", stores);
return Mono.just(dataexchange);
Then stores is populated as empty list in response. However, I can verify that subscribe() is working after returning response.
When I do :
return mono.flatmap( (response) -> {
dataexchange.put("stores", response));
return Mono.just(dataexchange);
});
Then stores is populated in the response.
Can someone please explain me what is the difference between the two? Is flatMap blocking?
Thanks in advance !
mono.subscribe(stores::addAll);
is asynchronous. That means, you tell the mono that it can now start evaluating.
What you do is continue processing stores right away - with a huge chance that the Mono hasn't evaluated yet.
So, how can you fix this?
You can block until the Mono has completed:
mono.doOnNext(stores::addAll).block()
Of course, this defeats the purpose of reactive programming. You are blocking the main thread until an action completes, which can be achieved without Reactor in a much simpler fashion.
The right way is to change the rest of your code to be reactive too, from head to toe. This is similar to your second example, where your call to dataexchange is part of the Mono, thus being evaluated asynchronously, too.
The important lesson to be learned is that operations like map or flatMap are not operating on the result of the Mono, but create a new Mono that adds another transformation to the execution of the original Mono. As long as the Mono doesn't evaluate, the flatMap or map operations are not actually doing anything.
I hope this helps.

Create BehaviorSubject from Observable

Say I have an observableA which gets data from network and emits it, if I do subscription to this observable each time it tries to request data from network which is heavy.
I want to create BehaviorSubject and connect it to observableA, so that any other threads/objects will subscribe to BehaviorSubject in order to get latest emitted data.
So far I couldnt manage it to code. I cannot create empty BehaviorSubject and call inside observableA, because they are not related to each other.
I cannot subscribe to observableA and get BehaviorSubject as observer, any idea how can I accomplish it? or maybe even better?
You can use multicast. E.g.,
Observable<String> o = ...;
ConnectableObservable<String> co = o.multicast(BehaviorSubject.<String> create());
co.connect();
co.subscribe(...);
co.subscribe(...);
co.subscribe(...);
I had similar scenario in javascript where I wrapped promise within Rx and I didn't want to make network call again when I subscribe to observable. This is how I ended up implementing:
subject = new Rx.AsyncSubject();
observable = Rx.Observable.fromPromise(....).subscribe(subject);
You can now consume the promise response as subject.subscribe(...) and it will always emit promise result from subject as we are using AsyncSubject (AsyncSubject - Represents the result of an asynchronous operation. The last value before the OnCompleted notification, or the error received through OnError, is sent to all subscribed observers).
In Rx.NET we'd use one of the Publish overloads that accepts an initialValue parameter. Essentially, it's just a shorter way of doing a multicast like zsxwing described. I'm not sure whether Rx.Java offers these overloaded Publish methods.