Skip to content

Instantly share code, notes, and snippets.

@ajliv
Last active September 3, 2016 16:49
Show Gist options
  • Save ajliv/efcd33297cca446131d6582a0eb21e6b to your computer and use it in GitHub Desktop.
Save ajliv/efcd33297cca446131d6582a0eb21e6b to your computer and use it in GitHub Desktop.
Rate limit tracker, adds a compounded penalty to the wait time with each offense over the limit
import { action, computed, observable, reaction, when } from 'mobx';
export default class RateLimiter {
@observable forgiveness;
@observable limit;
@observable offenses = 0;
@observable queue = [];
@observable wait;
@computed get compoundedPenalty() {
const i = (this.offenses - this.forgiveness) || 0;
return (i * 1000);
}
@computed get overLimit() {
return (this.queue.length >= this.limit);
}
constructor(limit = 3, wait = 4000, forgiveness = 1) {
this.forgiveness = forgiveness;
this.limit = limit;
this.wait = wait;
this.offenseHandler = reaction(() => this.overLimit, (overLimit) => {
if (overLimit) this.offenses += 1;
});
}
@action add = () => {
if (this.overLimit) return false;
let q = setTimeout(() => remove(), this.wait + this.compoundedPenalty);
const remove = action(() => this.queue.remove(q));
this.queue.push(q);
when(() => this.queue.indexOf(q) === -1, () => {
clearTimeout(q);
q = null;
});
return remove;
};
@action destroy = () => {
this.offenseHandler();
this.queue.clear();
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment