Skip to content

Commit 9f6d98e

Browse files
committed
Revert "Revert "Refactor RateLimitUtil for improved concurrency (#68)""
This reverts commit ef16af5.
1 parent 8f3ca79 commit 9f6d98e

File tree

1 file changed

+16
-17
lines changed

1 file changed

+16
-17
lines changed
Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
package app.util
22

33
import io.javalin.Javalin
4-
import java.util.*
54
import java.util.concurrent.ConcurrentHashMap
5+
import java.util.concurrent.Executors
6+
import java.util.concurrent.TimeUnit
67

78
/**
89
* A very naive IP-based rate-limiting mechanism
@@ -21,30 +22,28 @@ object RateLimitUtil {
2122
fun enableTerribleRateLimiting(app: Javalin) {
2223

2324
app.before { ctx ->
24-
if (ipReqCount[ctx.ip()] ?: 0 > 25) {
25-
throw TerribleRateLimitException()
26-
}
27-
ipReqCount[ctx.ip()] = (ipReqCount[ctx.ip()] ?: 0) + 1
25+
ipReqCount.compute(ctx.ip(), { _, count ->
26+
when (count) {
27+
null -> 1
28+
in 0..25 -> count + 1
29+
else -> throw TerribleRateLimitException()
30+
}
31+
})
2832
}
2933

30-
app.exception(TerribleRateLimitException::class.java) { e, ctx ->
34+
app.exception(TerribleRateLimitException::class.java) { _, ctx ->
3135
ctx.result("You can't spam this much. I'll give you a new request every five seconds.")
3236
}
3337

34-
Timer().scheduleAtFixedRate(decrementAllCounters(), 0, 5000) // every 5s
38+
Executors.newSingleThreadScheduledExecutor()
39+
.scheduleAtFixedRate(decrementAllCounters, 0, 5, TimeUnit.SECONDS)
3540

3641
}
3742

38-
private fun decrementAllCounters() = object : TimerTask() {
39-
override fun run() {
40-
ipReqCount.forEach { ip, count ->
41-
if (count > 0) {
42-
ipReqCount[ip] = ipReqCount[ip]!! - 1
43-
} else {
44-
ipReqCount.remove(ip)
45-
}
46-
}
47-
}
43+
private val decrementAllCounters = Runnable {
44+
ipReqCount.forEachKey(1, { ip ->
45+
ipReqCount.computeIfPresent(ip, { _, count -> if (count > 1) count - 1 else null })
46+
})
4847
}
4948

5049
}

0 commit comments

Comments
 (0)