
org.perfcake.message.generator.ConstantSpeedMessageGenerator Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of perfcake Show documentation
Show all versions of perfcake Show documentation
A Lightweight Performance Testing Framework
/*
* -----------------------------------------------------------------------\
* PerfCake
*
* Copyright (C) 2010 - 2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* -----------------------------------------------------------------------/
*/
package org.perfcake.message.generator;
/**
* A generator that tries to achieve given speed of messages per second.
* Uses the underlying buffer of {@link SenderTask SenderTasks} in {@link DefaultMessageGenerator}.
* This buffer smoothens the changes in the speed. If you need the generator to change its speed
* more aggressively, configure {@link DefaultMessageGenerator#setSenderTaskQueueSize(int)}.
*
* @author Martin Večeřa
*/
public class ConstantSpeedMessageGenerator extends DefaultMessageGenerator {
/**
* The desired constant speed in messages per second.
*/
private double speed = 5000;
/**
* Buffer of recent times when a task was added. Its size is equal to the speed, so the smallest
* time in the buffer (the oldest record) should be around 1000ms from now. Smaller time difference
* means that we are too fast. Larger time difference means we are too slow.
*/
private long[] buffer;
/**
* Pointer to the buffer - we use it as a circular buffer.
*/
private int pointer = 0;
/**
* Duration of a break between two submitted tasks in case the speed is lower than 1000 messages per second.
*/
private int breakDuration;
private long getSmallest() {
return buffer[(pointer + 1) % (int) Math.round(Math.ceil(speed))];
}
private long getLast() {
return buffer[pointer];
}
private void addTime(final long time) {
pointer = (pointer + 1) % (int) Math.round(Math.ceil(speed));
buffer[pointer] = time;
}
/**
* Gets the desired constant speed in messages per second.
*
* @return The speed.
*/
public double getSpeed() {
return speed;
}
/**
* Sets the desired constant speed in messages per second.
*
* @param speed
* The speed in messages per second.
* @return Instance of this for fluent API.
*/
public ConstantSpeedMessageGenerator setSpeed(final double speed) {
this.speed = speed;
if (speed > 0) { // -1 = unlimited speed
buffer = new long[(int) Math.round(Math.ceil(speed))];
pointer = 0;
for (int i = 0; i < (int) Math.round(Math.ceil(speed)); i++) {
buffer[i] = 0;
}
breakDuration = (int) Math.round(1000 / speed); // will be 0 for speed > 1000
}
return this;
}
@Override
protected boolean prepareTask() throws InterruptedException {
if (speed == -1) {
return super.prepareTask();
}
long currentTime = System.currentTimeMillis();
// the size of the buffer = speed, so the smallest time should be around one second old
// in case of a non-zero breakDuration, we cannot submit a task before the break passed
if (currentTime - getSmallest() > 1000 && (!(breakDuration > 0) || currentTime - breakDuration >= getLast())) {
boolean res = super.prepareTask();
if (res) {
addTime(currentTime);
}
return res;
}
return false;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy