Как отсортировать мульти в smallrye mutiny

Другие реактивные библиотеки, такие как projectactor, предлагают методы сортировки для издателей, но в бунте такого метода нет. В их документации об этом даже не говорится.

https://smallrye.io/smallrye-mutiny

Прямо сейчас я достигаю указанной функциональности, делая это

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

Есть ли лучший способ сделать то же самое?

3 ответа

Решение

Я не верю, что есть встроенный / лучший способ сделать это.

Mutiny обычно ценится за наличие "урезанного" набора операторов в своем ядре и за возможность создавать другие, более сложные операторы по мере необходимости. Они пытаются избежать ситуации с реактором, когда вы используете более 100 методов для пары основных типов, и без достаточных базовых знаний часто трудно понять, какие из них актуальны.

ИМХО, это не плохо. В других реактивных фреймворках определенно есть эти встроенные sort()операторов, но здесь есть опасность - люди предполагают, что они все еще могут относиться к ним как к бесконечным, волшебным образом отсортированным издателям, потому что нигде нет никаких следов каких-либо коллекций. Вы, конечно, не можете - внутренне эти структуры должны поддерживать базовую коллекцию для сортировки данных, а затем просто выводить ее содержимое, когда поток завершен. Однако это не так ясно, и незнание этого факта часто может привести к непреднамеренному замедлению и OutOfMemoryError. Напротив, в вашем примере сразу очевидно, что этот поток использует базовую коллекцию для сортировки ваших данных.

Есть только одна незначительная вещь, которую я бы изменил в вашем примере, но не совсем связанный с вашим вопросом - я бы использовал:

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

... в вызове карты вместо сортировки изменяемого списка. Мутации структур данных в реактивном потоке - это немного запах кода.

Другой подход, который я использовал, — объединять мульти в TreeMap, как только они приходят с .collect().in(TREE_MAP_SUPPLIER, MULTI_MAP_ACCUMULATOR)

  1. Преобразуйте Multi в Uni (список).
  2. Отсортируйте список из Uni.
  3. Преобразование Uni в 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
Другие вопросы по тегам