public CompletableFuture<Stream<MessageResult>> retrieveMessages(List<ComposedMessageIdWithMetaData> messageIds, FetchType fetchType, Limit limit) { return CompletableFutureUtil.chainAll( limit.applyOnStream(messageIds.stream().distinct()) .collect(JamesCollectors.chunker(configuration.getMessageReadChunkSize())), ids -> rowToMessages(fetchType, ids)) .thenApply(stream -> stream.flatMap(Function.identity())); }
@Test public void chainAllShouldNotThrowOnEmptyStream() { Stream<Integer> result = CompletableFutureUtil.chainAll(Stream.<Integer>of(), i -> CompletableFuture.supplyAsync(() -> i, executorService)) .join(); assertThat(result.collect(Guavate.toImmutableList())) .isEmpty(); }
@Test void chainAllShouldNotThrowOnEmptyStream() { Stream<Integer> result = CompletableFutureUtil.chainAll(Stream.<Integer>of(), i -> CompletableFuture.supplyAsync(() -> i, executorService)) .join(); assertThat(result.collect(Guavate.toImmutableList())) .isEmpty(); }
@Test public void chainAllShouldPreserveOrder() { int itemCount = 10; ImmutableList<Integer> ints = IntStream.range(0, itemCount) .boxed() .collect(Guavate.toImmutableList()); Stream<Integer> result = CompletableFutureUtil.chainAll(ints.stream(), i -> CompletableFuture.supplyAsync(() -> i, executorService)) .join(); assertThat(result.collect(Guavate.toImmutableList())) .containsExactlyElementsOf(ints); }
@Test void chainAllShouldPreserveOrder() { int itemCount = 10; ImmutableList<Integer> ints = IntStream.range(0, itemCount) .boxed() .collect(Guavate.toImmutableList()); Stream<Integer> result = CompletableFutureUtil.chainAll(ints.stream(), i -> CompletableFuture.supplyAsync(() -> i, executorService)) .join(); assertThat(result.collect(Guavate.toImmutableList())) .containsExactlyElementsOf(ints); }
@Test void chainAllShouldPreserveExecutionOrder() { int itemCount = 10; ImmutableList<Integer> ints = IntStream.range(0, itemCount) .boxed() .collect(Guavate.toImmutableList()); ConcurrentLinkedDeque<Integer> queue = new ConcurrentLinkedDeque<>(); CompletableFutureUtil.chainAll(ints.stream(), i -> CompletableFuture.supplyAsync(() -> { try { Thread.sleep(itemCount - i); } catch (InterruptedException e) { throw new RuntimeException(e); } queue.add(i); return i; }, executorService)) .join(); assertThat(queue) .containsExactlyElementsOf(ints); }
@Test public void chainAllShouldPreserveExecutionOrder() { int itemCount = 10; ImmutableList<Integer> ints = IntStream.range(0, itemCount) .boxed() .collect(Guavate.toImmutableList()); ConcurrentLinkedDeque<Integer> queue = new ConcurrentLinkedDeque<>(); CompletableFutureUtil.chainAll(ints.stream(), i -> CompletableFuture.supplyAsync(() -> { try { Thread.sleep(itemCount - i); } catch (InterruptedException e) { throw Throwables.propagate(e); } queue.add(i); return i; }, executorService)) .join(); assertThat(queue) .containsExactlyElementsOf(ints); }