All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.blazemeter.jmeter.threads.arrivals.ArrivalsThreadGroup Maven / Gradle / Ivy
package com.blazemeter.jmeter.threads.arrivals;
import com.blazemeter.jmeter.control.VirtualUserController;
import com.blazemeter.jmeter.threads.AbstractDynamicThreadGroup;
import com.blazemeter.jmeter.threads.DynamicThread;
import org.apache.jmeter.engine.StandardJMeterEngine;
import org.apache.jmeter.threads.JMeterContextService;
import org.apache.jmeter.threads.JMeterThread;
import org.apache.jmeter.threads.ListenerNotifier;
import org.apache.jmeter.threads.ThreadCountsAccessor;
import org.apache.jorphan.collections.ListedHashTree;
import org.apache.jorphan.logging.LoggingManager;
import org.apache.log.Logger;
import java.util.Collections;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
public class ArrivalsThreadGroup extends AbstractDynamicThreadGroup {
public static final String CONCURRENCY_LIMIT = "ConcurrencyLimit";
public static final String ARRIVALS_LIMIT = "ArrivalsLimit";
private static final Logger log = LoggingManager.getLoggerForClass();
protected final AtomicLong arrivalsCount = new AtomicLong();
protected final AtomicLong completionsCount = new AtomicLong();
protected AtomicLong abandonsCount = new AtomicLong();
protected final Set poolThreads = Collections.newSetFromMap(new ConcurrentHashMap());
@Override
public void start(int groupIndex, ListenerNotifier listenerNotifier, ListedHashTree testTree, StandardJMeterEngine engine) {
super.start(groupIndex, listenerNotifier, testTree, engine);
synchronized (this) {
try {
wait();
log.info("Got first arrival");
} catch (InterruptedException e) {
log.warn("Interrupted start", e);
}
}
}
public int getNumThreads() {
return threads.size();
}
@Override
public void addThread(DynamicThread threadWorker) {
super.addThread(threadWorker);
JMeterContextService.addTotalThreads(1);
}
@Override
protected Thread getThreadStarter(int groupIndex, ListenerNotifier listenerNotifier, ListedHashTree testTree, StandardJMeterEngine engine) {
return new ArrivalsThreadStarter(groupIndex, listenerNotifier, testTree, engine, this);
}
@Override
public void startNextLoop() {
((VirtualUserController) getSamplerController()).startNextLoop();
}
/**
* Forceful stop of test calls this
*/
@Override
public void stop() {
super.stop();
for (DynamicThread thread : poolThreads) {
thread.interruptOSThread();
}
}
/**
* Graceful shutdown of test calls this, then #verifyThreadsStopped
*/
@Override
public void tellThreadsToStop() {
super.tellThreadsToStop();
for (DynamicThread thread : poolThreads) {
stopThread(thread.getThreadName(), true);
}
}
@Override
public boolean verifyThreadsStopped() {
boolean parent = super.verifyThreadsStopped();
log.info("Verify shutdown thread counts: " + threads.size() + "/" + poolThreads.size());
return parent && poolThreads.isEmpty();
}
public boolean movedToPool(DynamicThread thread) {
threads.remove(thread);
if (thread.isStopping()) {
log.debug("Did not move into pool, because thread is stopping: " + thread);
return false;
}
poolThreads.add(thread);
log.debug("Moved thread to pool: " + thread + ", pool size: " + poolThreads.size());
ThreadCountsAccessor.decrNumberOfThreads();
//noinspection SynchronizationOnLocalVariableOrMethodParameter
synchronized (thread) {
try {
thread.wait();
} catch (InterruptedException e) {
log.debug("Interrupted", e);
}
}
ThreadCountsAccessor.incrNumberOfThreads();
return running;
}
public synchronized boolean releasedPoolThread() {
if (poolThreads.isEmpty()) {
return false;
}
DynamicThread thread = poolThreads.toArray(new DynamicThread[poolThreads.size()])[0];
poolThreads.remove(thread);
threads.add(thread);
log.debug("Releasing pool thread: " + thread + ", pool size: " + poolThreads.size());
//noinspection SynchronizationOnLocalVariableOrMethodParameter
synchronized (thread) {
thread.notify();
}
return true;
}
public boolean isLimitReached() {
long limit;
try {
limit = Long.parseLong(getArrivalsLimit());
} catch (NumberFormatException e) {
log.error("Invalid arrivals limit, defaulting to 0");
limit = 0;
}
return !(limit <= 0 || arrivalsCount.longValue() < limit);
}
public synchronized void arrivalFact(JMeterThread thread, long arrivalID) {
arrivalsCount.incrementAndGet();
notifyAll();
saveLogRecord("ARRIVAL", thread.getThreadName(), thread.getThreadNum() + "." + arrivalID);
}
public void completionFact(JMeterThread thread, long arrivalID) {
completionsCount.incrementAndGet();
saveLogRecord("COMPLETION", thread.getThreadName(), thread.getThreadNum() + "." + arrivalID);
}
public void abandonFact(JMeterThread thread, long arrivalID) {
abandonsCount.incrementAndGet();
saveLogRecord("ABANDONMENT", thread.getThreadName(), thread.getThreadNum() + "." + arrivalID);
}
public boolean canCreateMoreThreads() {
try {
long limit = Long.parseLong(getConcurrencyLimit());
return limit <= 0 || threads.size() < limit;
} catch (NumberFormatException e) {
log.debug("Invalid concurrency limit, defaulting to 0");
return true;
}
}
public void setConcurrencyLimit(String value) {
setProperty(CONCURRENCY_LIMIT, value);
}
public String getConcurrencyLimit() {
return getPropertyAsString(CONCURRENCY_LIMIT, "");
}
public void setArrivalsLimit(String value) {
setProperty(ARRIVALS_LIMIT, value);
}
public String getArrivalsLimit() {
return getPropertyAsString(ARRIVALS_LIMIT, "0");
}
@Override
public void testEnded(String s) {
releaseAllPoolThreads();
super.testEnded(s);
log.info("Done " + arrivalsCount.longValue() + " arrivals, " + completionsCount.longValue() + " completions, " + abandonsCount.longValue() + " abandonments");
log.debug("Pool size: " + poolThreads.size());
}
public void releaseAllPoolThreads() {
for (DynamicThread thread : poolThreads) {
//noinspection SynchronizationOnLocalVariableOrMethodParameter
synchronized (thread) {
thread.interrupt();
thread.interruptOSThread();
thread.notify();
}
}
}
}