This is an automated email from the ASF dual-hosted git repository. fschumacher pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/jmeter.git
commit 9e2e2bcbd13d128c0d887a23e67e2e7a9dcf9355 Author: Felix Schumacher <[email protected]> AuthorDate: Wed Sep 25 12:28:54 2024 +0200 Add startTime to AbstractThreadGroup and use it in OMTG and PreciseThroughputTimer A thread group might start later than the test. When we calculate delays on the start time of the test, we might get a stampede of samples run at the start of the thread group. --- .../poissonarrivals/PreciseThroughputTimer.java | 4 ++-- .../apache/jmeter/engine/StandardJMeterEngine.java | 1 + .../apache/jmeter/threads/AbstractThreadGroup.java | 20 ++++++++++++++++++++ .../jmeter/threads/openmodel/OpenModelThreadGroup.kt | 2 +- xdocs/changes.xml | 4 +++- 5 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/components/src/main/java/org/apache/jmeter/timers/poissonarrivals/PreciseThroughputTimer.java b/src/components/src/main/java/org/apache/jmeter/timers/poissonarrivals/PreciseThroughputTimer.java index 4864e22117..ee4998a62c 100644 --- a/src/components/src/main/java/org/apache/jmeter/timers/poissonarrivals/PreciseThroughputTimer.java +++ b/src/components/src/main/java/org/apache/jmeter/timers/poissonarrivals/PreciseThroughputTimer.java @@ -99,7 +99,7 @@ public class PreciseThroughputTimer extends AbstractTestElement implements Clone nextEvent = events.next(); } long now = System.currentTimeMillis(); - long testStarted = JMeterContextService.getTestStartTime(); + long testStarted = JMeterContextService.getContext().getThreadGroup().getStartTime(); long delay = (long) (nextEvent * TimeUnit.SECONDS.toMillis(1) + testStarted - now); if (log.isDebugEnabled()) { log.debug("Calculated delay is {}", delay); @@ -117,7 +117,7 @@ public class PreciseThroughputTimer extends AbstractTestElement implements Clone } private EventProducer getEventProducer() { - long testStarted = JMeterContextService.getTestStartTime(); + long testStarted = JMeterContextService.getContext().getThreadGroup().getStartTime(); long prevStarted = PREV_TEST_STARTED.get(); if (prevStarted != testStarted && PREV_TEST_STARTED.compareAndSet(prevStarted, testStarted)) { // Reset counters if we are calculating throughput for a new test, see https://github.com/apache/jmeter/issues/6165 diff --git a/src/core/src/main/java/org/apache/jmeter/engine/StandardJMeterEngine.java b/src/core/src/main/java/org/apache/jmeter/engine/StandardJMeterEngine.java index a72602fb2e..618f5b9212 100644 --- a/src/core/src/main/java/org/apache/jmeter/engine/StandardJMeterEngine.java +++ b/src/core/src/main/java/org/apache/jmeter/engine/StandardJMeterEngine.java @@ -574,6 +574,7 @@ public class StandardJMeterEngine implements JMeterEngine, Runnable { threadGroupTree.add(group, testLevelElements); groups.add(group); + group.setStartTime(System.currentTimeMillis()); group.start(groupCount, notifier, threadGroupTree, this); } catch (JMeterStopTestException ex) { // NOSONAR Reported by log JMeterUtils.reportErrorToUser("Error occurred starting thread group :" + group.getName()+ ", error message:"+ex.getMessage() diff --git a/src/core/src/main/java/org/apache/jmeter/threads/AbstractThreadGroup.java b/src/core/src/main/java/org/apache/jmeter/threads/AbstractThreadGroup.java index 37b3f104b2..63a4462a4d 100644 --- a/src/core/src/main/java/org/apache/jmeter/threads/AbstractThreadGroup.java +++ b/src/core/src/main/java/org/apache/jmeter/threads/AbstractThreadGroup.java @@ -21,6 +21,7 @@ import java.io.Serializable; import java.time.Duration; import java.util.IdentityHashMap; import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; import org.apache.jmeter.control.Controller; import org.apache.jmeter.control.IteratingController; @@ -86,6 +87,8 @@ public abstract class AbstractThreadGroup extends AbstractTestElement private final AtomicInteger numberOfThreads = new AtomicInteger(0); // Number of active threads in this group + private final AtomicLong startTime = new AtomicLong(0); + @Override public AbstractThreadGroupSchema getSchema() { return AbstractThreadGroupSchema.INSTANCE; @@ -97,6 +100,23 @@ public abstract class AbstractThreadGroup extends AbstractTestElement return new PropertiesAccessor<>(this, getSchema()); } + /** + * Get the time when this thread group has been started + * @return time in milliseconds since epoch + */ + public long getStartTime() { + return startTime.get(); + } + + /** + * Set the time when this thread group has been started.<br> + * Will probably be set by StandardJMeterEngine. + * @param startTime time in milliseconds since epoch + */ + public void setStartTime(long startTime) { + this.startTime.set(startTime); + } + /** {@inheritDoc} */ @Override public boolean isDone() { diff --git a/src/core/src/main/kotlin/org/apache/jmeter/threads/openmodel/OpenModelThreadGroup.kt b/src/core/src/main/kotlin/org/apache/jmeter/threads/openmodel/OpenModelThreadGroup.kt index 5948dc6d40..45c0f6cef6 100644 --- a/src/core/src/main/kotlin/org/apache/jmeter/threads/openmodel/OpenModelThreadGroup.kt +++ b/src/core/src/main/kotlin/org/apache/jmeter/threads/openmodel/OpenModelThreadGroup.kt @@ -204,7 +204,7 @@ public class OpenModelThreadGroup : val seed = randomSeed val rnd = if (seed == 0L) Random() else Random(seed) val gen = ThreadScheduleProcessGenerator(rnd, parsedSchedule) - val testStartTime = System.currentTimeMillis() + val testStartTime = this.startTime val executorService = Executors.newCachedThreadPool() this.executorService = executorService val starter = ThreadsStarter(testStartTime, executorService, activeThreads, gen) { threadNumber -> diff --git a/xdocs/changes.xml b/xdocs/changes.xml index 60836279fd..025af48bca 100644 --- a/xdocs/changes.xml +++ b/xdocs/changes.xml @@ -57,7 +57,7 @@ JMeter 6.x requires Java 17 or later for execution (Java 21 is recommended). Summary </p> <ul> -<li><a href="#Bug fixes">Bug fixes</a></li> +<li><a href="#Changes">Changes</a></li> </ul> <ch_section>Changes</ch_section> @@ -65,6 +65,8 @@ Summary <ul> <li><pr>6220</pr> Require Java 17 or later for running JMeter</li> <li><pr>6274</pr> Change references to old MySQL driver to new class <code>com.mysql.cj.jdbc.Driver</code></li> + <li><issue>6352</issue> Calculate delays in Open Model Thread Group and Precise Throughput + Timer relative to start of Thread Group instead of the start of the test.</li> </ul> <!-- =================== Thanks =================== -->
