Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nonlinear Workload - Decimal Ramp Rate #287

Merged
merged 6 commits into from
Nov 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
import java.util.concurrent.Semaphore;

import com.google.common.collect.ImmutableMap;
import com.intuit.tank.harness.logging.LogEvent;
import com.intuit.tank.http.TankHttpClient;
import com.intuit.tank.vm.api.enumerated.*;
import org.apache.commons.io.FileUtils;
Expand Down Expand Up @@ -311,13 +310,10 @@ private void startHttp(String baseUrl) {
agentRunData.setSimulationTimeMillis(startData.getSimulationTime());
agentRunData.setAgentInstanceNum(startData.getAgentInstanceNum());
agentRunData.setTotalAgents(startData.getTotalAgents());
agentRunData.setTargetRampRate(startData.getTargetRampRate()); // non-linear: same ramp rate set for each agent - total ramp rate determined by number of agents

ThreadContext.put("workloadType", agentRunData.getIncrementStrategy().getDisplay());

if(startData.getIncrementStrategy().equals(IncrementStrategy.standard)){
endRampRate = agentRunData.getUserInterval();
LOG.info(new ObjectMessage(ImmutableMap.of("Message", "Nonlinear - targetRampRate = " + endRampRate + " users/sec for job " + agentRunData.getJobId())));
}

if (startData.getDataFiles() != null) {
for (DataFileRequest dfRequest : startData.getDataFiles()) {
Expand Down Expand Up @@ -714,8 +710,8 @@ public void checkAgentThreads() {
}
if (hasMetSimulationTime()) { // && doneSignal.getCount() != 0) {
if(agentRunData.getIncrementStrategy().equals(IncrementStrategy.increasing)) {
LOG.info(LogUtil.getLogMessage("Max simulation time has been met and there are "
+ doneSignal.getCount() + " threads not reporting done."));
LOG.info(LogUtil.getLogMessage("Linear - Max simulation time has been met and there are "
+ doneSignal.getCount() + " threads not reporting done, interrupting remaining threads."));
for (Thread t : sessionThreads) {
if (t.isAlive()) {
LOG.warn(LogUtil.getLogMessage("thread " + t.getName() + '-' + t.getId()
Expand All @@ -724,42 +720,30 @@ public void checkAgentThreads() {
doneSignal.countDown();
}
}
} else {
LOG.info(LogUtil.getLogMessage("Max simulation time has been met and there are "
+ semaphore.availablePermits() + " threads not reporting done."));
for (Thread t : sessionThreads) {
if (t.isAlive()) {
LOG.warn(LogUtil.getLogMessage("thread " + t.getName() + '-' + t.getId()
+ " is still running with a State of " + t.getState().name(), LogEventType.System));
t.interrupt();
}
}
}
}
// Clean up TestPlanRunner Threads that are Thread.State.TERMINATED
sessionThreads.removeIf(t -> t.getState().equals(Thread.State.TERMINATED));
}

private void configureNonlinearAgentRunData(){
double baseDelay = (((double) agentRunData.getRampTimeMillis() / 1000) / (endRampRate));
int order = agentRunData.getAgentInstanceNum();
int numAgents = agentRunData.getTotalAgents();

// Calculate the target ramp rate and remaining ramp time for each agent
int baseRampRate = (int) (endRampRate / numAgents);
int remainingRampRate = (int) (endRampRate % numAgents);
// non-linear: configure agentRunData for non-linear ramping
if(endRampRate < 1){ // if ramp rate < 1, ramp from 0 to ramp rate over ramp time
double rampTime = (double) agentRunData.getRampTimeMillis() / 1000;
agentRunData.setInitialDelay(rampTime);
agentRunData.setRampRateDelay(rampTime);
agentRunData.setBaseDelay(rampTime);
} else {
double baseDelay = (((double) agentRunData.getRampTimeMillis() / 1000) / (endRampRate * agentRunData.getTotalAgents()));
int order = agentRunData.getAgentInstanceNum();

int targetRampRate = baseRampRate;
if(order <= remainingRampRate){
targetRampRate += 1;
agentRunData.setInitialDelay(order * baseDelay); // order: order # * baseDelay
agentRunData.setRampRateDelay((((double) agentRunData.getRampTimeMillis() / 1000) / (endRampRate))); // rampRateDelay: total ramp time / targetRampRate
agentRunData.setBaseDelay(baseDelay); // baseDelay: total ramp time / endRampRate - used to ramp agents from 0 to 1 user/sec
}

agentRunData.setInitialDelay(order * baseDelay); // order: order # * baseDelay
agentRunData.setRampRateDelay((((double) agentRunData.getRampTimeMillis() / 1000) / (targetRampRate))); // rampRateDelay: total ramp time / targetRampRate
agentRunData.setTargetRampRate(targetRampRate); // targetRampRate: endRampRate / # of agents while accounting for uneven division
agentRunData.setBaseDelay(baseDelay); // baseDelay: total ramp time / endRampRate - used to ramp agents from 0 to 1 user/sec
LOG.info(new ObjectMessage(ImmutableMap.of("Message", "Non-Linear Multi-agent Orchestration: \n" +
"agentOrder=" + order + "; \n" +
"agentOrder=" + agentRunData.getAgentInstanceNum() + "; \n" +
"initialDelay=" + agentRunData.getInitialDelay() + "; \n" +
"rampRateDelay=" + agentRunData.getRampRateDelay() + "; \n" +
"agentTargetRampRate=" + agentRunData.getTargetRampRate())));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public class AgentRunData {
private double baseDelay = 0;
private double initialDelay = 0;
private double rampRateDelay = 0;
private double targetRampRate = 1;
private double targetRampRate = 1.0;
private String testPlans = "";
private String instanceId;
private String jobId = "0";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public class TestPlanStarter implements Runnable {
private int sessionStarts = 0;
private int totalTps = 0;
private final long rampDelay;
private int currentRampRate;
private double currentRampRate;
private boolean done = false;

public TestPlanStarter(Object httpClient, HDTestPlan plan, int numThreads, String tankHttpClientClass, ThreadGroup threadGroup, AgentRunData agentRunData) {
Expand Down Expand Up @@ -176,7 +176,11 @@ public void run() {
}

intialDelay(); // initial delay
currentRampRate++; // after delay, start ramp rate at 1 user/sec
if(agentRunData.getTargetRampRate() < 1.0){
currentRampRate = agentRunData.getTargetRampRate(); // after delay, start and keep ramp rate at < 1 user/sec value
} else {
currentRampRate++; // after delay, start ramp rate at 1 user/sec
}

long lastRampRateAddition = (long) (System.currentTimeMillis() - (agentRunData.getBaseDelay() * 1000));
double agentTimer = ((System.currentTimeMillis() - lastRampRateAddition)) / 1000.0; // start agent timer at base delay
Expand Down Expand Up @@ -262,7 +266,7 @@ public void run() {
sendCloudWatchMetrics(activeCount); // send metrics every 30 seconds

try {
Thread.sleep(1000 / currentRampRate); // sleep between adding users proportional to current ramp rate
Thread.sleep((long) (1000 / currentRampRate)); // sleep between adding users proportional to current ramp rate
} catch (InterruptedException e) {
LOG.error(LogUtil.getLogMessage("Error trying to wait for ramp", LogEventType.System), e);
}
Expand Down Expand Up @@ -418,7 +422,7 @@ private void sendCloudWatchMetrics(long activeCount) {
datumList.add(MetricDatum.builder()
.metricName("userRampRate")
.unit(StandardUnit.COUNT)
.value((double) this.currentRampRate)
.value(this.currentRampRate)
.timestamp(timestamp)
.dimensions(testPlan, instanceId, jobId)
.build());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ public void testConfigureNonlinearAgentRunData() {
MockFlowController controller = new MockFlowController();
instance.setFlowControllerTemplate(controller);

instance.setEndRampRate(10);
instance.setEndRampRate(1);
instance.getAgentRunData().setAgentInstanceNum(1);
instance.getAgentRunData().setTotalAgents(10);
instance.getAgentRunData().setRampTimeMillis(500);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"userIntervalIncrement",
"agentInstanceNum",
"totalAgents",
"targetRampRate",
"scriptUrl",
"dataFile"
})
Expand Down Expand Up @@ -73,6 +74,9 @@ public class AgentTestStartData implements Serializable {
@XmlElement(name = "totalAgents", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false)
private int totalAgents;

@XmlElement(name = "targetRampRate", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false)
private double targetRampRate;

@XmlElement(name = "dataFile", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false)
private DataFileRequest[] dataFile;

Expand All @@ -96,6 +100,7 @@ public AgentTestStartData(AgentTestStartData copy) {
this.userIntervalIncrement = copy.userIntervalIncrement;
this.agentInstanceNum = copy.agentInstanceNum;
this.totalAgents = copy.totalAgents;
this.targetRampRate = copy.targetRampRate;
}

/**
Expand Down Expand Up @@ -207,6 +212,21 @@ public void setTotalAgents(int totalAgents) {
this.totalAgents = totalAgents;
}

/**
* @return
*/
public double getTargetRampRate() {
return targetRampRate;
}

/**
* @param targetRampRate
* the targetRampRate to set
*/
public void setTargetRampRate(double targetRampRate) {
this.targetRampRate = targetRampRate;
}

/**
* {@inheritDoc}
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public interface JobRequest extends Serializable {
/**
* @return the endRate
*/
public abstract int getEndRate();
public abstract double getEndRate();

/**
* @return the numAgents
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public final class JobRequestImpl implements Serializable, JobRequest {
private int numUsersPerAgent;
private int numAgents;
private int startRate;
private int endRate;
private double endRate;
private String scriptsXmlUrl;

public static Builder builder() {
Expand Down Expand Up @@ -236,15 +236,15 @@ public void setStartRate(int startRate) {
/**
* @return the endRate
*/
public int getEndRate() {
public double getEndRate() {
return endRate;
}

/**
* @param endRate
* the endRate to set
*/
public void setEndRate(int endRate) {
public void setEndRate(double endRate) {
this.endRate = endRate;
}

Expand Down Expand Up @@ -312,6 +312,7 @@ public String toString() {
.append("useEips", useEips)
.append("baselineVirtualUsers", baselineVirtualUsers)
.append("userIntervalIncrement", userIntervalIncrement)
.append("endRate", endRate)
.append("reportingMode", reportingMode)
.append("regions", regions)
.toString();
Expand Down Expand Up @@ -410,7 +411,7 @@ public GeneratorT withStartRate(int aValue) {
return (GeneratorT) this;
}

public GeneratorT withEndRate(int aValue) {
public GeneratorT withEndRate(double aValue) {
instance.endRate= aValue;
return (GeneratorT) this;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ public void testToString() {
.append("useEips", request.isUseEips())
.append("baselineVirtualUsers", request.getBaselineVirtualUsers())
.append("userIntervalIncrement", "0")
.append("endRate", "0.0")
.append("reportingMode", request.getReportingMode())
.append("regions", request.getRegions())
.toString();
Expand Down
21 changes: 20 additions & 1 deletion data_model/src/main/java/com/intuit/tank/project/BaseJob.java
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@ public abstract class BaseJob extends BaseEntity {
@Column(name = "user_interval_increment_seconds")
private int userIntervalIncrement;

@Column(name = "target_rate")
private Double targetRampRate = 1.00;

@Column(name = "reporting_mode", nullable = false)
private String reportingMode = TankConstants.RESULTS_NONE;

Expand All @@ -121,6 +124,7 @@ public BaseJob(BaseJob copy) {
this.simulationTime = copy.simulationTime;
this.terminationPolicy = copy.terminationPolicy;
this.userIntervalIncrement = copy.userIntervalIncrement;
this.targetRampRate = copy.targetRampRate;
this.location = copy.location;
this.reportingMode = copy.reportingMode;
this.allowOverride = copy.allowOverride;
Expand Down Expand Up @@ -434,4 +438,19 @@ public void setUserIntervalIncrement(int userIntervalIncrement) {
this.userIntervalIncrement = userIntervalIncrement;
}

}
/**
* @return the targetRampRate
*/
public double getTargetRampRate() {
return targetRampRate != null ? targetRampRate : 1.0;
}

/**
* @param targetRampRate
* the targetRampRate to set
*/
public void setTargetRampRate(double targetRampRate) {
this.targetRampRate = targetRampRate;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,12 @@ protected static String buildDetails(JobValidator validator, Workload workload,
}
addProperty(sb, "Ramp Time", TimeUtil.toTimeString(proposedJobInstance.getRampTime()));
if(proposedJobInstance.getIncrementStrategy().equals(IncrementStrategy.standard)){
// addProperty(sb, "Starting User Ramp (users/sec)", Integer.toString(proposedJobInstance.getStartRate()));
addProperty(sb, "Target User Ramp Rate (users/sec)", Integer.toString(proposedJobInstance.getUserIntervalIncrement()));
addProperty(sb, "Agent User Ramp Rate (users/sec)", Double.toString(proposedJobInstance.getTargetRampRate()));
addProperty(sb, "Total User Ramp Rate (users/sec)", Double.toString(proposedJobInstance.getTargetRampRate() * proposedJobInstance.getNumAgents()));
addProperty(sb, "Estimated Steady State Concurrent Users",
Double.toString(proposedJobInstance.getTargetRampRate() *
((double) proposedJobInstance.getRampTime() / 1000) *
proposedJobInstance.getNumAgents()));
}
addProperty(sb, "Initial Users", Integer.toString(proposedJobInstance.getBaselineVirtualUsers()));
if(proposedJobInstance.getIncrementStrategy().equals(IncrementStrategy.increasing)) {
Expand Down Expand Up @@ -149,13 +153,6 @@ protected static String buildDetails(JobValidator validator, Workload workload,
if (regionPercentage != 100) {
addError(errorSB, "Region Percentage does not add up to 100%");
}

if(proposedJobInstance.getNumAgents() > proposedJobInstance.getUserIntervalIncrement()
&& proposedJobInstance.getIncrementStrategy().equals(IncrementStrategy.standard)) {
addError(errorSB, "Number of Agents cannot be greater than the Target User Ramp Rate"
+ "- update Target User Ramp Rate or set Number of Agents equal to or less than " + proposedJobInstance.getUserIntervalIncrement() + " agents");
}

}
sb.append(BREAK);
sb.append(BREAK);
Expand Down Expand Up @@ -221,7 +218,7 @@ protected static String buildDetails(JobValidator validator, Workload workload,
if(proposedJobInstance.getIncrementStrategy().equals(IncrementStrategy.increasing)) {
target = "(" + numUsers + " users)";
} else {
target = "(" + proposedJobInstance.getUserIntervalIncrement() + " users/sec)";
target = "(" + proposedJobInstance.getTargetRampRate() * proposedJobInstance.getNumAgents() + " users/sec)";
}
addProperty(
sb,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,8 @@ public AgentTestStartData registerAgentForJob(AgentData agentData) {
ret.setStartUsers(jobInfo.jobRequest.getBaselineVirtualUsers());
ret.setTotalAgents(jobInfo.numberOfMachines);
ret.setIncrementStrategy(jobInfo.jobRequest.getIncrementStrategy());
ret.setUserIntervalIncrement(jobInfo.jobRequest.getUserIntervalIncrement()); // non-linear: target ramp rate
ret.setUserIntervalIncrement(jobInfo.jobRequest.getUserIntervalIncrement());
ret.setTargetRampRate(jobInfo.jobRequest.getEndRate());
jobInfo.agentData.add(agentData);
CloudVmStatus status = vmTracker.getStatus(agentData.getInstanceId());
if(status != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ private JobRequest jobToJobRequest(JobInstance job) {
.withSimulationTime(job.getSimulationTime()).withStatus(job.getStatus())
.withTerminationPolicy(job.getTerminationPolicy())
.withUserIntervalIncrement(job.getUserIntervalIncrement())
.withEndRate(job.getUserIntervalIncrement())
.withEndRate(job.getTargetRampRate())
.withRegions(getRegions(job))
.withNofitications(getNotifications(job))
.withDataFileIds(getDataFileIds(job));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -240,18 +240,18 @@ public void setWorkloadType(String workloadType) {
/**
* @return the end rate for job
*/
public int getEndRate() {
return getWorkload().getJobConfiguration().getUserIntervalIncrement();
public double getEndRate() {
return getWorkload().getJobConfiguration().getTargetRampRate();
}

/**
* Sets the end rate for the job
*
* @param endRate
*/
public void setEndRate(int endRate) {
public void setEndRate(double endRate) {
Workload workload = getWorkload();
workload.getJobConfiguration().setUserIntervalIncrement(endRate);
workload.getJobConfiguration().setTargetRampRate(endRate);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public ActJobNodeBean(JobInstance job, boolean hasRights, FastDateFormat fmt) {
this.setRegion("");
this.setActiveUsers(String.valueOf(job.getBaselineVirtualUsers()));
this.setTotalUsers(String.valueOf(job.getTotalVirtualUsers()));
this.setTargetRampRate(String.valueOf(job.getUserIntervalIncrement()));
this.setTargetRampRate(String.valueOf(job.getTargetRampRate() * job.getNumAgents()));
this.jobDetails = job.getJobDetails();
this.setStartTime(job.getStartTime());
this.setEndTime(job.getEndTime());
Expand Down
Loading