package com.griddynamics.jagger.engine.e1.scenario;
import com.google.common.collect.Maps;
import com.griddynamics.jagger.coordinator.NodeId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.math.BigDecimal;
import java.util.Map;
import java.util.Set;
/**
* Workload Clock to control qps load
*/
public class QpsClock implements WorkloadClock {
private final int tickInterval;
private final int maxThreads;
private final DesiredTps desiredQps;
private Logger log = LoggerFactory.getLogger(this.getClass());
public QpsClock(int tickInterval, int maxThreads, DesiredTps desiredTps) {
this.tickInterval = tickInterval;
this.maxThreads = maxThreads;
this.desiredQps = desiredTps;
}
@Override
public Map<NodeId, Integer> getPoolSizes(Set<NodeId> nodes) {
Map<NodeId, Integer> result = Maps.newHashMap();
for (NodeId node : nodes) {
result.put(node, maxThreads);
}
return result;
}
private final BigDecimal ONE_TENTH = BigDecimal.valueOf(1D / 10D);
@Override
public void tick(WorkloadExecutionStatus status, WorkloadAdjuster adjuster) {
// spare qps between Nodes
Set<NodeId> nodes = status.getNodes();
BigDecimal currentQps = desiredQps.get(System.currentTimeMillis());
log.debug("current qps value to schedule = {} ", currentQps);
if (currentQps.compareTo(ONE_TENTH) < 0) {
currentQps = ONE_TENTH;
log.debug("new calculated qps : " + currentQps);
}
// period per node in milliseconds
long periodPerNode = BigDecimal.valueOf(1000L).divide(currentQps, BigDecimal.ROUND_DOWN).longValue()
* nodes.size();
log.debug("period per node = {}", periodPerNode);
for(NodeId node : status.getNodes()) {
WorkloadConfiguration workloadConfiguration = WorkloadConfiguration.with(
periodPerNode,
maxThreads);
log.debug("adjust workload configuration {} to node with identifier {}", workloadConfiguration, node.getIdentifier());
adjuster.adjustConfiguration(node, workloadConfiguration);
}
}
@Override
public int getTickInterval() {
return tickInterval;
}
@Override
public int getValue() {
return desiredQps.getDesiredTps().intValue();
}
@Override
public String toString() {
return getValue() + " rps";
}
}