com.blazemeter.jmeter.threads.AbstractThreadStarter Maven / Gradle / Ivy
package com.blazemeter.jmeter.threads;
import com.blazemeter.jmeter.control.VirtualUserController;
import kg.apc.jmeter.threads.AbstractSimpleThreadGroup;
import org.apache.jmeter.control.Controller;
import org.apache.jmeter.engine.StandardJMeterEngine;
import org.apache.jmeter.engine.TreeCloner;
import org.apache.jmeter.threads.JMeterContext;
import org.apache.jmeter.threads.JMeterContextService;
import org.apache.jmeter.threads.ListenerNotifier;
import org.apache.jmeter.util.JMeterUtils;
import org.apache.jorphan.collections.HashTree;
import org.apache.jorphan.collections.ListedHashTree;
import org.slf4j.LoggerFactory;
import org.slf4j.Logger;
public abstract class AbstractThreadStarter extends Thread {
private static final Logger log = LoggerFactory.getLogger(AbstractThreadStarter.class);
protected final ListenerNotifier notifier;
protected final ListedHashTree threadGroupTree;
protected final StandardJMeterEngine engine;
protected final JMeterContext context;
protected final AbstractDynamicThreadGroup owner;
protected final int groupIndex;
protected long threadIndex = 0;
protected HashTree treeClone;
protected double startTime = 0;
public AbstractThreadStarter(int groupIndex, AbstractDynamicThreadGroup owner, ListedHashTree listedHashTree, ListenerNotifier listenerNotifier, StandardJMeterEngine standardJMeterEngine) {
super();
this.owner = owner;
this.treeClone = cloneTree(listedHashTree); // it needs owner inside
this.engine = standardJMeterEngine;
this.groupIndex = groupIndex;
this.threadGroupTree = listedHashTree;
this.notifier = listenerNotifier;
this.context = JMeterContextService.getContext();
setDaemon(true);
}
@Override
public void run() {
try {
// Copy in ThreadStarter thread context from calling Thread
JMeterContextService.getContext().setVariables(this.context.getVariables());
supplyActiveThreads();
} catch (InterruptedException e) {
log.debug("Interrupted", e);
// "InterruptedException" should not be ignored (squid:S2142)
Thread.currentThread().interrupt();
}
log.debug("Thread starter has done its job");
}
protected abstract void supplyActiveThreads() throws InterruptedException;
protected DynamicThread makeThread(long threadIndex) {
boolean onErrorStopTest = owner.getOnErrorStopTest();
boolean onErrorStopTestNow = owner.getOnErrorStopTestNow();
boolean onErrorStopThread = owner.getOnErrorStopThread();
boolean onErrorStartNextLoop = owner.getOnErrorStartNextLoop();
final DynamicThread jmeterThread = new DynamicThread(treeClone, this.owner, notifier);
jmeterThread.setThreadNum((int) threadIndex);
jmeterThread.setThreadGroup(this.owner);
jmeterThread.setInitialContext(context);
String groupName = getName();
String distributedPrefix = JMeterUtils.getPropDefault(AbstractSimpleThreadGroup.THREAD_GROUP_DISTRIBUTED_PREFIX_PROPERTY_NAME, "");
final String threadName = distributedPrefix + (distributedPrefix.isEmpty() ? "" : "-") + groupName + " " + groupIndex + "-" + (threadIndex + 1);
jmeterThread.setThreadName(threadName);
jmeterThread.setEngine(engine);
jmeterThread.setOnErrorStopTest(onErrorStopTest);
jmeterThread.setOnErrorStopTestNow(onErrorStopTestNow);
jmeterThread.setOnErrorStopThread(onErrorStopThread);
jmeterThread.setOnErrorStartNextLoop(onErrorStartNextLoop);
return jmeterThread;
}
// had to copy it from ThreadGroup
protected ListedHashTree cloneTree(ListedHashTree tree) {
TreeCloner cloner = new TreeCloner(true);
tree.traverse(cloner);
ListedHashTree clonedTree = cloner.getClonedTree();
if (!clonedTree.isEmpty()) {
Object firstElement = clonedTree.getArray()[0];
Controller samplerController = ((AbstractDynamicThreadGroup) firstElement).getSamplerController();
if (samplerController instanceof VirtualUserController) {
assert owner != null;
((VirtualUserController) samplerController).setOwner(owner);
}
}
return clonedTree;
}
protected DynamicThread addActiveThread() {
DynamicThread threadWorker = makeThread(threadIndex++);
owner.addThread(threadWorker);
Thread thread = new Thread(threadWorker, threadWorker.getThreadName());
threadWorker.setOSThread(thread);
thread.setDaemon(false); // we can't have it daemon, since it will stay and eat RAM in UI mode
thread.start();
treeClone = cloneTree(threadGroupTree); // use background time to clone tree
return threadWorker;
}
}