How do i sort a Multi in smallrye mutiny

1.9k views Asked by At

Other reactive libraries like project reactor offer sort methods for Publishers but there is no such method in mutiny. Their documentation doesn't even talk about it.

https://smallrye.io/smallrye-mutiny

Right now i'm achieving the said functionality by doing this

multi.collectItems()
.asList()
.map(
list -> {
  list.sort();
  return list;
})
.convert()
.with(listUni -> Multi.createFrom().iterable(listUni.await().indefinitely()))

Is there a better way to do the same ?

3

There are 3 answers

1
Michael Berry On BEST ANSWER

I don't believe there is a built-in/better way to do this.

Mutiny generally prizes itself on having a "cut-down" set of operators in its core, and letting you build up other, more complex operators as needed. They're trying to avoid the reactor situation where you have 100+ methods on a couple of core types, and without a lot of background knowledge it's often difficult to know what ones are relevant.

IMHO that's no bad thing. Other reactive frameworks definitely have these built-in sort() operators, but there's a danger here - people assume they can still treat them as infinite, magically sorted publishers, because there's no sign of any collections anywhere. You can't of course - internally these frameworks have to maintain an underlying collection to sort the data, and then just output the contents of that when the stream is complete. This isn't that clear however, and ignorance of this fact can often lead to unintended slowdowns and OutOfMemoryError. On the contrary, in your example, it's immediately obvious that this stream uses an underlying collection for sorting your data.

There's just one minor thing I'd change in your example, but not really related to your question - I'd use:

list.stream().sorted().collect(Collectors.toList())

...in your map call instead of sorting a mutable list. Mutating data structures in a reactive stream is a bit of a code smell.

0
Dexter On

Another approach I used - combine multis into TreeMap as soon as they come with .collect().in(TREE_MAP_SUPPLIER, MULTI_MAP_ACCUMULATOR)

0
swerts On
  1. Convert the Multi to Uni (list).
  2. Sort the list from Uni.
  3. Convert the Uni to a Multi
multi.collect().asList() //1
.onItem()
.transform(list -> list.stream().sorted(Comparator.comparing(item::getId)).toList()) //2
.onItem()
.transformToMulti(list -> Multi.createFrom().iterable(list)); //3