com.blazemeter.jmeter.threads.concurrency.ConcurrencyThreadStarter Maven / Gradle / Ivy
package com.blazemeter.jmeter.threads.concurrency;
import com.blazemeter.jmeter.threads.AbstractThreadStarter;
import com.blazemeter.jmeter.threads.DynamicThread;
import org.apache.jmeter.engine.StandardJMeterEngine;
import org.apache.jmeter.threads.ListenerNotifier;
import org.apache.jmeter.util.JMeterUtils;
import org.apache.jorphan.collections.ListedHashTree;
import org.apache.jorphan.logging.LoggingManager;
import org.apache.log.Logger;
public class ConcurrencyThreadStarter extends AbstractThreadStarter {
private static final Logger log = LoggingManager.getLoggerForClass();
private final ConcurrencyThreadGroup concurrTG;
public ConcurrencyThreadStarter(int groupIndex, ListenerNotifier listenerNotifier, ListedHashTree testTree, StandardJMeterEngine engine, ConcurrencyThreadGroup concurrencyThreadGroup) {
super(groupIndex, concurrencyThreadGroup, testTree, listenerNotifier, engine);
concurrTG = concurrencyThreadGroup;
}
@Override
protected void supplyActiveThreads() throws InterruptedException {
log.info("Start supplying threads");
startTime = System.currentTimeMillis();
while (!owner.isLimitReached() && getPlannedConcurrency() >= 0) {
log.debug("Concurrency factual/expected: " + concurrTG.getConcurrency() + "/" + getPlannedConcurrency());
while (concurrTG.getConcurrency() < getPlannedConcurrency()) {
DynamicThread thread = addActiveThread();
concurrTG.threadStarted(thread);
}
concurrTG.waitThreadStopped();
}
log.info("Done supplying threads");
}
private long getPlannedConcurrency() {
long rampUp = owner.getRampUpSeconds();
long hold = owner.getHoldSeconds();
long steps = owner.getStepsAsLong();
double maxConcurr = owner.getTargetLevelAsDouble();
double timeOffset = (System.currentTimeMillis() - startTime) / 1000.0;
log.debug("Time progress: " + timeOffset + "/" + (rampUp + hold));
long shift = JMeterUtils.getPropDefault("dynamic_tg.shift_rampup_start", 0L);
timeOffset -= shift;
if (timeOffset < 0) {
timeOffset = 0;
}
if (timeOffset >= rampUp + hold) {
return -1; // means no more concurrency needed
}
if (rampUp == 0 || timeOffset > rampUp) {
return Math.round(maxConcurr);
} else if (steps > 0) {
double stepSize = maxConcurr / (double) steps;
double stepLen = rampUp / (double) steps;
return Math.round(stepSize * (Math.floor(timeOffset / stepLen) + 1));
} else {
double slope = maxConcurr / rampUp;
return Math.round(slope * timeOffset);
}
}
}