1- // Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved.
1+ // Copyright (c) 2007-2022 VMware, Inc. or its affiliates. All rights reserved.
22//
33// This software, the RabbitMQ Java client library, is triple-licensed under the
44// Mozilla Public License 2.0 ("MPL"), the GNU General Public License version 2
3232import java .net .URISyntaxException ;
3333import java .security .KeyManagementException ;
3434import java .security .NoSuchAlgorithmException ;
35+ import java .time .Duration ;
3536import java .util .ArrayList ;
3637import java .util .Collection ;
3738import java .util .Collections ;
@@ -61,14 +62,6 @@ public class MulticastSet {
6162 // from Java Client ConsumerWorkService
6263 public final static int DEFAULT_CONSUMER_WORK_SERVICE_THREAD_POOL_SIZE = Runtime .getRuntime ().availableProcessors () * 2 ;
6364 private static final Logger LOGGER = LoggerFactory .getLogger (MulticastSet .class );
64- /**
65- * Why 50? This is arbitrary. The fastest rate is 1 message / second when
66- * using a publishing interval, so 1 thread should be able to keep up easily with
67- * up to 50 messages / seconds (ie. 50 producers). Then, a new thread is used
68- * every 50 producers. This is 20 threads for 1000 producers, which seems reasonable.
69- * There's a command line argument to override this anyway.
70- */
71- private static final int PUBLISHING_INTERVAL_NB_PRODUCERS_PER_THREAD = 50 ;
7265 private static final String PRODUCER_THREAD_PREFIX = "perf-test-producer-" ;
7366 static final String STOP_REASON_REACHED_TIME_LIMIT = "Reached time limit" ;
7467 private final Stats stats ;
@@ -149,7 +142,28 @@ protected static int nbThreadsForConsumer(MulticastParams params) {
149142 protected static int nbThreadsForProducerScheduledExecutorService (MulticastParams params ) {
150143 int producerExecutorServiceNbThreads = params .getProducerSchedulerThreadCount ();
151144 if (producerExecutorServiceNbThreads <= 0 ) {
152- return params .getProducerThreadCount () / PUBLISHING_INTERVAL_NB_PRODUCERS_PER_THREAD + 1 ;
145+ int producerThreadCount = params .getProducerThreadCount ();
146+ Duration publishingInterval = params .getPublishingInterval () == null ? Duration .ofSeconds (1 )
147+ : params .getPublishingInterval ();
148+ long publishingIntervalMs = publishingInterval .toMillis ();
149+
150+ double publishingIntervalSeconds = (double ) publishingIntervalMs / 1000d ;
151+ double rate = (double ) producerThreadCount / publishingIntervalSeconds ;
152+ /**
153+ * Why 100? This is arbitrary. We assume 1 thread is more than enough to handle
154+ * the publishing of 100 messages in 1 second, the fastest rate
155+ * being 10 messages / second when using --publishing-interval.
156+ * Then, a new thread is used
157+ * every for every 100 messages / second.
158+ * This is 21 threads for 1000 producers publishing 1 message / second,
159+ * which seems reasonable.
160+ * There's a command line argument to override this anyway.
161+ */
162+ int threadCount = (int ) (rate / 100d ) + 1 ;
163+ LOGGER .debug ("Using {} thread(s) to schedule {} publisher(s) publishing every {} ms" ,
164+ threadCount , producerThreadCount , publishingInterval .toMillis ()
165+ );
166+ return threadCount ;
153167 } else {
154168 return producerExecutorServiceNbThreads ;
155169 }
@@ -406,9 +420,9 @@ private void startConsumers(Runnable[] consumerRunnables) throws InterruptedExce
406420
407421 private void startProducers (AgentState [] producerStates ) {
408422 this .messageSizeIndicator .start ();
409- if (params .getPublishingInterval () > 0 ) {
423+ if (params .getPublishingInterval () != null ) {
410424 ScheduledExecutorService producersExecutorService = this .threadingHandler .scheduledExecutorService (
411- PRODUCER_THREAD_PREFIX , nbThreadsForConsumer (params )
425+ PRODUCER_THREAD_PREFIX , nbThreadsForProducerScheduledExecutorService (params )
412426 );
413427 Supplier <Integer > startDelaySupplier ;
414428 if (params .getProducerRandomStartDelayInSeconds () > 0 ) {
@@ -417,13 +431,13 @@ PRODUCER_THREAD_PREFIX, nbThreadsForConsumer(params)
417431 } else {
418432 startDelaySupplier = () -> 0 ;
419433 }
420- int publishingInterval = params .getPublishingInterval ();
434+ Duration publishingInterval = params .getPublishingInterval ();
421435 for (int i = 0 ; i < producerStates .length ; i ++) {
422436 AgentState producerState = producerStates [i ];
423437 int delay = startDelaySupplier .get ();
424438 producerState .task = producersExecutorService .scheduleAtFixedRate (
425439 producerState .runnable .createRunnableForScheduling (),
426- delay , publishingInterval , TimeUnit .SECONDS
440+ delay , publishingInterval . toMillis () , TimeUnit .MILLISECONDS
427441 );
428442 }
429443 } else {
0 commit comments