Author: pmouawad
Date: Sun Mar  3 20:23:18 2019
New Revision: 1854738

URL: http://svn.apache.org/viewvc?rev=1854738&view=rev
Log:
Bug 58183 - Rampup may not be respected if thread take time to start leading to 
threads continuing to start post ramp up time
Bugzilla Id: 58183

Modified:
    jmeter/trunk/src/core/org/apache/jmeter/threads/ThreadGroup.java
    jmeter/trunk/xdocs/changes.xml

Modified: jmeter/trunk/src/core/org/apache/jmeter/threads/ThreadGroup.java
URL: 
http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/threads/ThreadGroup.java?rev=1854738&r1=1854737&r2=1854738&view=diff
==============================================================================
--- jmeter/trunk/src/core/org/apache/jmeter/threads/ThreadGroup.java (original)
+++ jmeter/trunk/src/core/org/apache/jmeter/threads/ThreadGroup.java Sun Mar  3 
20:23:18 2019
@@ -216,21 +216,31 @@ public class ThreadGroup extends Abstrac
         this.threadGroupTree = threadGroupTree;
         int numThreads = getNumThreads();
         int rampUpPeriodInSeconds = getRampUp();
-        float perThreadDelayInMillis = (float) (rampUpPeriodInSeconds * 1000) 
/ (float) getNumThreads();
-
         delayedStartup = isDelayedStartup(); // Fetch once; needs to stay 
constant
-        log.info("Starting thread group... number={} threads={} ramp-up={} 
perThread={} delayedStart={}", groupNumber,
-                numThreads, rampUpPeriodInSeconds, perThreadDelayInMillis, 
delayedStartup);
+        log.info("Starting thread group... number={} threads={} ramp-up={} 
delayedStart={}", groupNumber,
+                numThreads, rampUpPeriodInSeconds, delayedStartup);
         if (delayedStartup) {
             threadStarter = new Thread(new ThreadStarter(notifier, 
threadGroupTree, engine), getName()+"-ThreadStarter");
             threadStarter.setDaemon(true);
             threadStarter.start();
             // N.B. we don't wait for the thread to complete, as that would 
prevent parallel TGs
         } else {
-            long now = System.currentTimeMillis(); // needs to be same time 
for all threads in the group
             final JMeterContext context = JMeterContextService.getContext();
+            long lastThreadStartInMillis = 0;
+            int delayForNextThreadInMillis = 0;
+            final int perThreadDelayInMillis = Math.round((float) 
rampUpPeriodInSeconds * 1000 / numThreads);
             for (int threadNum = 0; running && threadNum < numThreads; 
threadNum++) {
-                startNewThread(notifier, threadGroupTree, engine, threadNum, 
context, now, (int)(threadNum * perThreadDelayInMillis));
+                long nowInMillis = System.currentTimeMillis();
+                if(threadNum > 0) {
+                    long timeElapsedToStartLastThread = nowInMillis - 
lastThreadStartInMillis;
+                    delayForNextThreadInMillis += perThreadDelayInMillis - 
timeElapsedToStartLastThread;
+                }
+                if (log.isDebugEnabled()) {
+                    log.debug("Computed delayForNextThreadInMillis:{} for 
thread:{}", delayForNextThreadInMillis);
+                }
+                lastThreadStartInMillis = nowInMillis;
+                startNewThread(notifier, threadGroupTree, engine, threadNum, 
context, nowInMillis,
+                        Math.max(0, delayForNextThreadInMillis));
             }
         }
         log.info("Started thread group number {}", groupNumber);
@@ -585,10 +595,14 @@ public class ThreadGroup extends Abstrac
                     }
                 }
                 final int numThreads = getNumThreads();
-                final int perThreadDelayInMillis = Math.round((float) 
(getRampUp() * 1000) / (float) numThreads);
+                final float rampUpOriginInMillis = (float) getRampUp() * 1000;
+                final long startTimeInMillis = System.currentTimeMillis();
                 for (int threadNumber = 0; running && threadNumber < 
numThreads; threadNumber++) {
                     if (threadNumber > 0) {
-                        pause(perThreadDelayInMillis); // ramp-up delay 
(except first)
+                        long elapsedInMillis = System.currentTimeMillis() - 
startTimeInMillis; 
+                        final int perThreadDelayInMillis = 
+                                Math.round(((rampUpOriginInMillis - 
elapsedInMillis) / (float) (numThreads - threadNumber)));
+                        pause(Math.max(0, perThreadDelayInMillis)); // ramp-up 
delay (except first)
                     }
                     if (usingScheduler && System.currentTimeMillis() > 
endtime) {
                         break; // no point continuing beyond the end time

Modified: jmeter/trunk/xdocs/changes.xml
URL: 
http://svn.apache.org/viewvc/jmeter/trunk/xdocs/changes.xml?rev=1854738&r1=1854737&r2=1854738&view=diff
==============================================================================
--- jmeter/trunk/xdocs/changes.xml [utf-8] (original)
+++ jmeter/trunk/xdocs/changes.xml [utf-8] Sun Mar  3 20:23:18 2019
@@ -173,6 +173,7 @@ Summary
     <li><bug>63201</bug>SearchTreeDialog disappears behind master JFrame. 
Contributed by Benoit Vatan (benoit.vatan at gmail.com)</li>
     <li><bug></bug><code>Function Helper Dialog</code>, <code>Export 
transactions for report</code> and <code>Import from cURL</code> disappear 
being master JFrame. Contributed by Ubik Load Pack (support at 
ubikloadpack.com)</li>
     <li><bug>63207</bug>java.lang.NullPointerException: null when run Jmeter 
5.1 with proxy options</li>
+    <li><bug>58183</bug>Rampup may not be respected if thread take time to 
start leading to threads continuing to start post ramp up time</li>
 </ul>
 
  <!--  =================== Thanks =================== -->


Reply via email to