Last active
September 3, 2016 16:49
-
-
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
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 { 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