fix: correct rate limit refresh
This commit is contained in:
+16
-5
@@ -1,12 +1,19 @@
|
|||||||
import gleam/dict.{type Dict}
|
import gleam/dict.{type Dict}
|
||||||
|
import gleam/erlang
|
||||||
import gleam/erlang/process
|
import gleam/erlang/process
|
||||||
import gleam/option.{type Option}
|
import gleam/option.{type Option}
|
||||||
import gleam/otp/actor
|
import gleam/otp/actor
|
||||||
|
import gleam/result
|
||||||
|
|
||||||
const max_requests_per_minute = 10
|
const max_requests_per_minute = 10
|
||||||
|
|
||||||
|
const rate_limit_window_seconds = 60
|
||||||
|
|
||||||
pub type StorageState {
|
pub type StorageState {
|
||||||
StorageState(pastes: Dict(String, String), rate_limits: Dict(String, Int))
|
StorageState(
|
||||||
|
pastes: Dict(String, String),
|
||||||
|
rate_limits: Dict(String, #(Int, Int)),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type StorageMsg {
|
pub type StorageMsg {
|
||||||
@@ -39,16 +46,20 @@ pub fn handle_message(state: StorageState, msg: StorageMsg) {
|
|||||||
actor.continue(StorageState(new_pastes, state.rate_limits))
|
actor.continue(StorageState(new_pastes, state.rate_limits))
|
||||||
}
|
}
|
||||||
CheckRateLimit(ip, reply) -> {
|
CheckRateLimit(ip, reply) -> {
|
||||||
let count =
|
let now = erlang.system_time(erlang.Second)
|
||||||
|
let #(count, window_start) =
|
||||||
state.rate_limits
|
state.rate_limits
|
||||||
|> dict.get(ip)
|
|> dict.get(ip)
|
||||||
|> option.from_result
|
|> result.unwrap(#(0, now))
|
||||||
|> option.unwrap(0)
|
let #(count, window_start) = case now - window_start >= rate_limit_window_seconds {
|
||||||
|
True -> #(0, now)
|
||||||
|
False -> #(count, window_start)
|
||||||
|
}
|
||||||
let allowed = count < max_requests_per_minute
|
let allowed = count < max_requests_per_minute
|
||||||
let new_limits = case allowed {
|
let new_limits = case allowed {
|
||||||
True ->
|
True ->
|
||||||
state.rate_limits
|
state.rate_limits
|
||||||
|> dict.insert(ip, count + 1)
|
|> dict.insert(ip, #(count + 1, window_start))
|
||||||
False -> state.rate_limits
|
False -> state.rate_limits
|
||||||
}
|
}
|
||||||
process.send(reply, allowed)
|
process.send(reply, allowed)
|
||||||
|
|||||||
Reference in New Issue
Block a user