kg.apc.jmeter.timers.VariableThroughputTimer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jmeter-plugins-standard Show documentation
Show all versions of jmeter-plugins-standard Show documentation
Custom plugins set for Apache JMeter
// TODO: fight with lagging on start
// TODO: create a thread which will wake up at least one sampler to provide rps
package kg.apc.jmeter.timers;
import java.util.ArrayList;
import kg.apc.jmeter.JMeterPluginsUtils;
import org.apache.jmeter.engine.StandardJMeterEngine;
import org.apache.jmeter.engine.util.NoThreadClone;
import org.apache.jmeter.gui.util.PowerTableModel;
import org.apache.jmeter.testelement.AbstractTestElement;
import org.apache.jmeter.testelement.TestStateListener;
import org.apache.jmeter.testelement.property.CollectionProperty;
import org.apache.jmeter.testelement.property.JMeterProperty;
import org.apache.jmeter.testelement.property.NullProperty;
import org.apache.jmeter.testelement.property.PropertyIterator;
import org.apache.jmeter.threads.JMeterContextService;
import org.apache.jmeter.timers.ConstantThroughputTimer;
import org.apache.jmeter.timers.Timer;
import org.apache.jmeter.util.JMeterUtils;
import org.apache.jorphan.logging.LoggingManager;
import org.apache.log.Logger;
/**
* @see ConstantThroughputTimer
*/
public class VariableThroughputTimer
extends AbstractTestElement
implements Timer, NoThreadClone, TestStateListener {
public static final String[] columnIdentifiers = new String[]{
"Start RPS", "End RPS", "Duration, sec"
};
public static final Class[] columnClasses = new Class[]{
String.class, String.class, String.class
};
// TODO: eliminate magic property
public static final String DATA_PROPERTY = "load_profile";
public static final int DURATION_FIELD_NO = 2;
public static final int FROM_FIELD_NO = 0;
public static final int TO_FIELD_NO = 1;
private static final Logger log = LoggingManager.getLoggerForClass();
/* put this in fields because we don't want create variables in tight loops */
private long cntDelayed;
private double time = 0;
private double msecPerReq;
private long cntSent;
private double rps;
private double startSec = 0;
private CollectionProperty overrideProp;
private int stopTries;
private double lastStopTry;
private boolean stopping;
public VariableThroughputTimer() {
super();
trySettingLoadFromProperty();
}
public long delay() {
synchronized (this) {
while (true) {
int delay;
long curTime = System.currentTimeMillis();
long msecs = curTime % 1000;
long secs = curTime - msecs;
checkNextSecond(secs);
delay = getDelay(msecs);
if (stopping) {
delay = delay > 0 ? 10 : 0;
notify();
}
if (delay < 1) {
notify();
break;
}
cntDelayed++;
try {
wait(delay);
} catch (InterruptedException ex) {
log.error("Waiting thread was interrupted", ex);
}
cntDelayed--;
}
cntSent++;
}
return 0;
}
private synchronized void checkNextSecond(double secs) {
// next second
if (time == secs) {
return;
}
if (startSec == 0) {
startSec = secs;
}
time = secs;
double nextRps = getRPSForSecond((secs - startSec) / 1000);
if (nextRps < 0) {
stopping = true;
rps = rps > 0 ? rps * (stopTries > 10 ? 2 : 1) : 1;
stopTest();
notifyAll();
} else {
rps = nextRps;
}
if (log.isDebugEnabled()) {
log.debug("Second changed " + ((secs - startSec) / 1000) + ", sleeping: " + cntDelayed + ", sent " + cntSent + ", RPS: " + rps);
}
if (cntDelayed < 1) {
log.warn("No free threads left in worker pool, made " + cntSent + '/' + rps + " samples");
}
cntSent = 0;
msecPerReq = 1000d / rps;
}
private int getDelay(long msecs) {
//log.info("Calculating "+msecs + " " + cntSent * msecPerReq+" "+cntSent);
if (msecs < (cntSent * msecPerReq)) {
return (int) (1 + 1000.0 * (cntDelayed + 1) / rps);
}
return 0;
}
void setData(CollectionProperty rows) {
setProperty(rows);
}
JMeterProperty getData() {
if (overrideProp != null) {
return overrideProp;
}
return getProperty(DATA_PROPERTY);
}
public double getRPSForSecond(double sec) {
JMeterProperty data = getData();
if (data instanceof NullProperty) return -1;
CollectionProperty rows = (CollectionProperty) data;
PropertyIterator scheduleIT = rows.iterator();
while (scheduleIT.hasNext()) {
ArrayList
© 2015 - 2024 Weber Informatics LLC | Privacy Policy