Created
March 8, 2022 23:02
-
-
Save itzg/4f4c57e4c8d7053aba788f95b2a8a4f4 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.time.Duration; | |
/** | |
* Tracks if a given activity has happened more times than the requested threshold | |
* within the requested time window. | |
* | |
* <p> | |
* <b>NOTE</b> this class is <b>not</b> thread-safe. This allows for optimal performance when | |
* concurrent access is not a factor. | |
* </p> | |
* | |
* <p> | |
* For example, to determine if an error has occurred more than 10 times within a | |
* 5 second window: | |
* <pre> | |
* TemporalFuse fuse = new TemporalFuse(10, Duration.ofSeconds(5)); | |
* . | |
* . | |
* . | |
* if (fuse.tick()) { | |
* log.error("That thing happened to many times.") | |
* } | |
* </pre> | |
* </p> | |
*/ | |
public class TemporalFuse { | |
private final long[] eventTimes; | |
private final long fuseDuration; | |
int pos = 0; | |
public TemporalFuse(int fuseCount, Duration fuseDuration) { | |
eventTimes = new long[fuseCount]; | |
this.fuseDuration = fuseDuration.toMillis(); | |
} | |
/** | |
* A user of this fuse should call this when the measured activity occurs. | |
* @return true if the fuse has gone over the threshold within the fuse duration | |
*/ | |
public boolean tick() { | |
final long currentTime = System.currentTimeMillis(); | |
eventTimes[pos++] = currentTime; | |
if (pos >= eventTimes.length) { | |
pos = 0; | |
} | |
final long fuseWindowStart = currentTime - fuseDuration; | |
for (final long eventTime : eventTimes) { | |
if (eventTime < fuseWindowStart) { | |
return false; | |
} | |
} | |
return true; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment