All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.perfcake.message.generator.ConstantSpeedMessageGenerator Maven / Gradle / Ivy

There is a newer version: 7.5
Show newest version
/*
 * -----------------------------------------------------------------------\
 * 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