package cc.blynk.server.core.stats.metrics;
import java.util.concurrent.TimeUnit;
import static java.lang.Math.*;
/**
* Class used to restrict user in request rate. Mostly copied from codahale metrics for performance improvement.
*
* The Blynk Project.
* Created by Dmitriy Dumanskiy.
* Created on 16.03.15.
*/
public class InstanceLoadMeter {
private static final long TICK_INTERVAL = TimeUnit.SECONDS.toMillis(1);
private static final double TICK_INTERVAL_DOUBLE = (double) TICK_INTERVAL;
private static final double ALPHA = 1 - exp(-1/60.0);
private long lastTick;
private long count = 0;
private boolean initialized = false;
private double rate = 0.0;
public InstanceLoadMeter() {
this.lastTick = System.currentTimeMillis();
}
/**
* Mark the occurrence of a given number of events.
*/
public void mark() {
tickIfNecessary();
count++;
}
private void tickIfNecessary() {
final long newTick = System.currentTimeMillis();
final long age = newTick - lastTick;
if (age > TICK_INTERVAL) {
lastTick = newTick - age % TICK_INTERVAL;
final long requiredTicks = age / TICK_INTERVAL;
for (long i = 0; i < requiredTicks; i++) {
tick();
}
}
}
public double getOneMinuteRateNoTick() {
return rate * TICK_INTERVAL_DOUBLE;
}
public double getOneMinuteRate() {
tickIfNecessary();
return rate * TICK_INTERVAL_DOUBLE;
}
private void tick() {
final double instantRate = count / TICK_INTERVAL_DOUBLE;
count = 0;
if (initialized) {
rate += (ALPHA * (instantRate - rate));
} else {
rate = instantRate;
initialized = true;
}
}
}