use of com.rabbitmq.stream.Producer in project rabbitmq-stream-java-client by rabbitmq.
the class StreamEnvironmentTest method growShrinkResourcesWhenProducersConsumersAreOpenedAndClosed.
@Test
void growShrinkResourcesWhenProducersConsumersAreOpenedAndClosed(TestInfo info) throws Exception {
int messageCount = 100;
int streamCount = 20;
int producersCount = ProducersCoordinator.MAX_PRODUCERS_PER_CLIENT * 3 + 10;
int consumersCount = ConsumersCoordinator.MAX_SUBSCRIPTIONS_PER_CLIENT * 2 + 10;
try (Environment environment = environmentBuilder.build()) {
List<String> streams = IntStream.range(0, streamCount).mapToObj(i -> streamName(info)).map(s -> {
environment.streamCreator().stream(s).create();
return s;
}).collect(Collectors.toCollection(() -> new CopyOnWriteArrayList<>()));
CountDownLatch confirmLatch = new CountDownLatch(messageCount * producersCount);
CountDownLatch consumeLatch = new CountDownLatch(messageCount * producersCount);
List<Producer> producers = IntStream.range(0, producersCount).mapToObj(i -> {
String s = streams.get(i % streams.size());
return environment.producerBuilder().stream(s).build();
}).collect(Collectors.toList());
List<Consumer> consumers = IntStream.range(0, consumersCount).mapToObj(i -> {
String s = streams.get(new Random().nextInt(streams.size()));
return environment.consumerBuilder().stream(s).messageHandler((offset, message) -> consumeLatch.countDown()).build();
}).collect(Collectors.toList());
producers.stream().parallel().forEach(producer -> {
IntStream.range(0, messageCount).forEach(messageIndex -> {
producer.send(producer.messageBuilder().addData("".getBytes()).build(), confirmationStatus -> {
if (confirmationStatus.isConfirmed()) {
confirmLatch.countDown();
}
});
});
});
assertThat(confirmLatch.await(10, SECONDS)).isTrue();
assertThat(consumeLatch.await(10, SECONDS)).isTrue();
EnvironmentInfo environmentInfo = MonitoringTestUtils.extract(environment);
assertThat(environmentInfo.getProducers()).hasSize(1);
int producerManagerCount = environmentInfo.getProducers().get(0).getClients().size();
assertThat(producerManagerCount).isPositive();
assertThat(environmentInfo.getConsumers()).hasSize(1);
int consumerManagerCount = environmentInfo.getConsumers().get(0).getClients().size();
assertThat(consumerManagerCount).isPositive();
java.util.function.Consumer<AutoCloseable> closing = agent -> {
try {
agent.close();
} catch (Exception e) {
throw new RuntimeException(e);
}
};
Collections.reverse(producers);
List<Producer> subProducers = producers.subList(0, ProducersCoordinator.MAX_PRODUCERS_PER_CLIENT);
subProducers.forEach(closing);
Collections.reverse(consumers);
List<Consumer> subConsumers = consumers.subList(0, ConsumersCoordinator.MAX_SUBSCRIPTIONS_PER_CLIENT);
subConsumers.forEach(closing);
producers.removeAll(subProducers);
consumers.removeAll(subConsumers);
environmentInfo = MonitoringTestUtils.extract(environment);
assertThat(environmentInfo.getProducers()).hasSize(1);
assertThat(environmentInfo.getProducers().get(0).getClients()).hasSizeLessThan(producerManagerCount);
assertThat(environmentInfo.getConsumers()).hasSize(1);
assertThat(environmentInfo.getConsumers().get(0).getClients()).hasSizeLessThan(consumerManagerCount);
producers.forEach(closing);
consumers.forEach(closing);
streams.stream().forEach(stream -> environment.deleteStream(stream));
}
}
use of com.rabbitmq.stream.Producer in project rabbitmq-stream-java-client by rabbitmq.
the class StreamProducerTest method firstMessagesShouldNotBeFilteredOutWhenNamedProducerRestarts.
@ParameterizedTest
@ValueSource(ints = { 1, 7 })
void firstMessagesShouldNotBeFilteredOutWhenNamedProducerRestarts(int subEntrySize, TestInfo info) throws Exception {
int messageCount = 10_000;
String producerName = info.getTestMethod().get().getName();
AtomicReference<Producer> producer = new AtomicReference<>(environment.producerBuilder().name(producerName).subEntrySize(subEntrySize).stream(stream).build());
AtomicReference<CountDownLatch> publishLatch = new AtomicReference<>(new CountDownLatch(messageCount));
IntConsumer publishing = i -> producer.get().send(producer.get().messageBuilder().addData("".getBytes()).build(), confirmationStatus -> publishLatch.get().countDown());
IntStream.range(0, messageCount).forEach(publishing);
assertThat(publishLatch.get().await(10, TimeUnit.SECONDS)).isTrue();
producer.get().close();
publishLatch.set(new CountDownLatch(messageCount));
producer.set(environment.producerBuilder().name(producerName).subEntrySize(subEntrySize).stream(stream).build());
IntStream.range(0, messageCount).forEach(publishing);
assertThat(publishLatch.get().await(10, TimeUnit.SECONDS)).isTrue();
producer.get().close();
CountDownLatch consumeLatch = new CountDownLatch(messageCount * 2);
environment.consumerBuilder().stream(stream).offset(OffsetSpecification.first()).messageHandler((ctx, msg) -> consumeLatch.countDown()).build();
assertThat(consumeLatch.await(10, TimeUnit.SECONDS)).isTrue();
}
use of com.rabbitmq.stream.Producer in project rabbitmq-stream-java-client by rabbitmq.
the class StreamProducerTest method sendWithMultipleProducers.
@Test
void sendWithMultipleProducers() throws Exception {
int batchSize = 10;
// don't want a multiple of batch size
int messageCount = 1_000 * batchSize + 1;
int nbProducers = 20;
Map<String, CountDownLatch> publishLatches = new ConcurrentHashMap<>(nbProducers);
Map<String, Producer> producers = new ConcurrentHashMap<>(nbProducers);
List<String> producerNames = IntStream.range(0, nbProducers).mapToObj(i -> {
String producerName = UUID.randomUUID().toString();
publishLatches.put(producerName, new CountDownLatch(messageCount));
producers.put(producerName, environment.producerBuilder().stream(stream).batchSize(batchSize).build());
return producerName;
}).collect(Collectors.toList());
AtomicLong count = new AtomicLong(0);
ExecutorService executorService = Executors.newCachedThreadPool();
try {
producerNames.forEach(name -> {
CountDownLatch publishLatch = publishLatches.get(name);
Producer producer = producers.get(name);
Runnable publishRunnable = () -> {
IntStream.range(0, messageCount).forEach(i -> {
producer.send(producer.messageBuilder().addData(name.getBytes()).build(), confirmationStatus -> {
count.incrementAndGet();
publishLatch.countDown();
});
});
};
executorService.submit(publishRunnable);
});
for (CountDownLatch publishLatch : publishLatches.values()) {
boolean completed = publishLatch.await(10, TimeUnit.SECONDS);
assertThat(completed).isTrue();
}
} finally {
executorService.shutdownNow();
}
}
use of com.rabbitmq.stream.Producer in project rabbitmq-stream-java-client by rabbitmq.
the class StreamProducerTest method sendWithSubEntryBatches.
@Test
void sendWithSubEntryBatches() throws Exception {
int batchSize = 100;
int messagesInBatch = 10;
// don't want a multiple of batch size
int messageCount = 1_000 * batchSize + 1;
CountDownLatch publishLatch = new CountDownLatch(messageCount);
Producer producer = environment.producerBuilder().stream(stream).subEntrySize(messagesInBatch).batchSize(batchSize).build();
IntStream.range(0, messageCount).forEach(i -> {
producer.send(producer.messageBuilder().addData("".getBytes()).build(), confirmationStatus -> {
publishLatch.countDown();
});
});
boolean completed = publishLatch.await(10, TimeUnit.SECONDS);
assertThat(completed).isTrue();
}
use of com.rabbitmq.stream.Producer in project rabbitmq-stream-java-client by rabbitmq.
the class StreamProducerTest method newIncarnationOfProducerCanQueryItsLastPublishingId.
@ParameterizedTest
@ValueSource(ints = { 1, 7 })
void newIncarnationOfProducerCanQueryItsLastPublishingId(int subEntrySize) throws Exception {
Producer p = environment.producerBuilder().name("producer-1").stream(stream).subEntrySize(subEntrySize).build();
AtomicReference<Producer> producer = new AtomicReference<>(p);
AtomicLong publishingSequence = new AtomicLong(0);
AtomicLong lastConfirmed = new AtomicLong(-1);
ConfirmationHandler confirmationHandler = confirmationStatus -> {
if (confirmationStatus.isConfirmed()) {
lastConfirmed.set(confirmationStatus.getMessage().getPublishingId());
}
};
AtomicBoolean canPublish = new AtomicBoolean(true);
Runnable publish = () -> {
while (canPublish.get()) {
producer.get().send(producer.get().messageBuilder().publishingId(publishingSequence.getAndIncrement()).addData(String.valueOf(publishingSequence.get()).getBytes()).build(), confirmationHandler);
}
};
new Thread(publish).start();
Thread.sleep(1000L);
canPublish.set(false);
waitAtMost(10, () -> publishingSequence.get() == lastConfirmed.get() + 1);
assertThat(lastConfirmed.get()).isPositive();
producer.get().close();
p = environment.producerBuilder().name("producer-1").stream(stream).subEntrySize(subEntrySize).build();
producer.set(p);
long lastPublishingId = producer.get().getLastPublishingId();
assertThat(lastPublishingId).isEqualTo(lastConfirmed.get());
canPublish.set(true);
new Thread(publish).start();
Thread.sleep(1000L);
canPublish.set(false);
waitAtMost(10, () -> publishingSequence.get() == lastConfirmed.get() + 1);
assertThat(lastConfirmed.get()).isGreaterThan(lastPublishingId);
CountDownLatch consumeLatch = new CountDownLatch((int) (lastConfirmed.get() + 1));
AtomicInteger consumed = new AtomicInteger();
environment.consumerBuilder().stream(stream).offset(OffsetSpecification.first()).messageHandler((offset, message) -> {
consumed.incrementAndGet();
consumeLatch.countDown();
}).build();
assertThat(consumeLatch.await(10, TimeUnit.SECONDS)).isTrue();
Thread.sleep(1000);
assertThat(consumed.get()).isEqualTo(lastConfirmed.get() + 1);
}
Aggregations