Make iterations of a loop sequentially in Mutiny - reactive-programming

I am new in the reactive programming world. I am currently working in a Java reactive application using the Mutiny library.
I need to develop a loop that waits for the previous iteration to finish in order to start the next one. For instance:
List<Uni<T>> uniList = new ArrayList<>();
for (T item : items) { //items is an already fulfilled collection
uniList.add(this.doSomethingAndReturnInUni(item));
}
return Uni.combine().all().unis(uniList).combinedWith(unisToCombine -> {
List<T> list = new ArrayList<>();
unisToCombine.forEach(x ->list.add(x));
return list;
});
The for loop in the example, generates a thread per iteration. I am wondering how to order the i-th call to the method doSomethingAndReturnInUni() waits for the (i-1) call to trigger the event, that is, make the for loop sequentially. It is possible to suscribe those events in such a way?

Could you try something like this?
Builder<Item> items = Uni.join().builder();
for (Item item : items) {
builder.add(this.doSomethingAndReturnInUni(item));
}
return builder.joinAll().andCollectFailures()
.flatMap(itemList -> do whatever you need ...) //itemList type is List<Item>

I don't know why you are using uni, as this should just handle one operation, for loops you should use multi, where you can handle the back pressure, and only get the next event, when one event is finished. Multi can be run sequentially and in parallel.
see https://quarkus.io/blog/mutiny-back-pressure/

I’ve done the same, using Multi’s see the ‘generateData()’ method here:
https://github.com/Serkan80/quarkus-quickstarts/blob/development/redis-streams-quickstart/weather-producer/src/main/java/org/acme/redis/streams/producer/ValuesGenerator.java

Related

Can I use AtomicReference to get value of a Mono and code still remain reactive

Sorry, I am new to reactive paradigm. Is is possible to use AtomicReference to get value of a Mono since reactive code can run asynchronously and different events run on different thread. Please see the sample below. I am also not sure if this piece of code is considered reactive
sample code:
public static void main(String[] a) {
AtomicReference<UserDTO> dto = new AtomicReference<>();
Mono.just(new UserDTO())
.doOnNext(d -> d.setUserId(123L))
.subscribe(d -> dto.set(d));
UserDTO result = dto.get();
dto.set(null);
System.out.println(result); // produce UserDTO(userId=123)
System.out.println(dto.get()); // produce null
}
The code snippet you have shared is not guaranteed to always work. There is no way to guarantee that the function inside doOnNext will happen before dto.get(). You have created a race condition.
You can run the follow code to simulate this.
AtomicReference<UserDTO> dto = new AtomicReference<>();
Mono.just(new UserDTO())
.delayElement(Duration.ofSeconds(1))
.doOnNext(d -> d.setUserId(123L))
.subscribe(dto::set);
UserDTO result = dto.get();
System.out.println(result); // produces null
To make this example fully reactive, you should print out in the subscribe operator
Mono.just(new UserDTO())
.doOnNext(d -> d.setUserId(123L))
.subscribe(System.out::println)
In a more "real world" example, your method would return a Mono<UserDTO> and you would then perform transformations on this using map or flatMap operators.
** EDIT **
If you are looking to make a blocking call within a reactive stream this previous stack overflow question contains a good answer

Multicast sticky observable with on subscribe/on dispose behavior

I'm trying to create an Observable with the following characteristics:
allows multiple concurrent and/or consecutive subscribers
emits the last emitted item to every new subscriber
does something when the first subscriber subscribes, and when the last subscription is disposed
A BehaviorSubject with doOnSubscribe/doOnDispose satisfies #1 and #2, but runs subscribe/dispose for every subscriber instead of only the first and last. Adding share satisfies #1 and #3, but only emits the last emitted item to the first concurrent subscriber.
I came up with a solution that seems to work but feels like an ugly hack:
AtomicInteger subs = new AtomicInteger();
Observable<String> test = BehaviorSubject.createDefault("foo")
.doOnSubscribe(x -> {
if(subs.getAndIncrement() == 0) {
// do something
}
})
.doOnDispose(() -> {
if(subs.decrementAndGet() == 0) {
// do something
}
});
Is there an existing operator or combination of operators that achieves the same effect?
Use the replay operator with argument 1 i.e.
yourObservable.replay(1)
Edit: You are right that replay will return a connectedObservable and that the refcount operator will make it behave like on Observable i.e.
yourObservable.replay(1).refcount()

Create infinite repeatable Observable from array

Let's say I have an array items
I know I can create an observable from this array using
Rx.Observable.fromArray(items)
How do I create a lazily infinitely repeating observable from this (i.e.: repeating the items as long as they are being requested)?
Tried
Rx.Observable.fromArray(items).repeat()
But this doesn't execute lazily and therefor locks up the browser.
You cannot do this with an Observable. You way want to look at using an Enumerable.
The Enumerable flavor of Reactive Extensions is known as Interective Extensions.
I'm still a newcomer to RxJS, so perhaps what I am proposing is complete madness, but could something along the lines of the following work for this?
var items = [1, 2, 3, 4, 5];
var infiniteSource = Rx.Observable.from(items)
.map(function (x) { return Rx.Observable.return(x).delay(1000); })
.concatAll()
.doWhile(function(_) { return true; /* i.e. never end */ });
infiniteSource.subscribe(function(x) { console.log(x); });
I have an example here: http://ctrlplusb.jsbin.com/sihewo/edit?js,console
The delay is put in there so as not to flood the console. In terms of the "until no longer needed part" perhaps an unsubscribe or other mechanism can be injected into the doWhile?

Significance of Publish().RefCount() in this example?

I am in the process of learning RX and have run across a sample on the Intro to Rx site that I have a question about. Here is the example which implements the same functionality as the Window with count extension method:
public static IObservable<IObservable<T>> MyWindow<T>(
this IObservable<T> source,
int count)
{
var shared = source.Publish().RefCount();
var windowEdge = shared
.Select((i, idx) => idx % count)
.Where(mod => mod == 0)
.Publish()
.RefCount();
return shared.Window(windowEdge, _ => windowEdge);
}
I understand the purpose of the var shared = source.Publish().RefCount() line to 'share' the source with the window edge query. What I don't understand is why the windowEdge query was also defined with the .Publish().RefCount()? Can someone please help me understand why this would be necessary?
Good Question!
Long Answer
Aside from performance reasons, the reason windowEdge is ref-counted has to do with the use of Select.
In this example, Select is using the index argument (idx), who's value is determined uniquely for each new subscriber. Therefore, if we did not ref-count windowEdge, each new subscriber would receive an event upon the next item yielded, since mod == 0 will always be true.
This means without ref-counting that each window would consist of exactly two values (assuming no other race conditions are introduced). Example:
When the first event fires, we create a new window and feed in the event, at which point we also use the window-closing selector to obtain an observable which will yield when the window should close. The next event fires, and is sent to the current window. That event also happens to be the first event that is sent to our window-closing observable (because mod == 0 is always true). The window-closing observable has now fired, and the window is closed, leaving us with a window which contains exactly two elements. Repeat.
TLDR
The use of ref-count for windowEdge is necessary to ensure we're only incrementing idx once per "MyWindow" observable.

List/Object searching in CoffeeScript

I'm trying to get my head around using CoffeeScript comprehensions as efficiently as possible. I think I have basic mapping down -- turning one list into another -- but searching still seems verbose to me.
Say I have a map of items to shops:
shopMap:
toyStore: ["games", "puzzles"]
bookStore: ["novels", "picture books"]
and, given an item, I want to find out which shop it's in. What's the best way of doing that in CoffeeScript?
Here's how I could do in in JavaScript:
var shop = findShop(item);
function findShop(item) {
for (shop in shopMap)
itemList = shopMap[shop]
for (i = 0, ii = itemList.length; i<ii; i++) {
if (itemList[i] === item) {
return shop;
}
}
}
}
I used a function to allow it to quickly break out of the loops with the return statement, instead of using breaks, but the function is kind of fugly as this is only being used once.
So is there a shorter CS equivalent preferably one that doesn't require creating a new function?
You can try this:
findShop = (item) ->
for shop, items of shopMap
return shop if item in items
If you really want to try with a list comprehension, this is equivalent:
findShop = (item) ->
(shop for shop, items of shopMap when item in items)[0]
But i think the first one reads better (and also doesn't need to generate an intermediate array for the results). This would be a better approach IMO if you wanted to find all shops for a given item:
findShops = (item) ->
shop for shop, items of shopMap when item in items
If this is a common operation, you might be better off creating an intermediate data structure up front and doing the lookup directly.
shopMap =
toyStore: ["games", "puzzles"]
bookStore: ["novels", "picture books"]
categoryMap = {}
for k, v of shopMap
for category in v
categoryMap[category] = k
alert(categoryMap['puzzles'])
Demo
With this implementation you need to loop through the structure only once up front (plus possibly update it if shopMap changes). With yours and epidemian's answer, you have to loop every time you need to do this particular type of lookup. If you do this operation a lot, it could make a difference. On the other hand, if your shopMap is really large (like thousands of entries), then my implementation will take up more memory.
Depending upon how robust you want to make this, you might want to turn it into a Class and have any operations on it occur through the Class' interface. You'd need addCategory and deleteCategory methods as well as a getStoreFromCategory method, which is essentially what we are implementing above. This object-oriented approach would hide the internal data-structure/implementation so you could later alter the implementation to optimize for memory or speed.