Posted to tcl by apn at Sat Feb 01 16:43:23 GMT 2025view pretty
# Code generated by ChatGPT
package require Tcl 8.6
package require tcltest
namespace eval RateLimiter {
variable limits
array set limits {}
proc allow_request {key max_requests time_window} {
variable limits
set now [clock milliseconds]
if {![info exists limits($key)]} {
set limits($key) "$max_requests $now"
}
lassign $limits($key) tokens last_time
set elapsed [expr {$now - $last_time}]
set new_tokens [expr {int($elapsed / $time_window) * $max_requests}]
set tokens [expr {min($tokens + $new_tokens, $max_requests)}]
set last_time [expr {$now - ($elapsed % $time_window)}]
if {$tokens > 0} {
set tokens [expr {$tokens - 1}]
set limits($key) "$tokens $last_time"
return 1
} else {
return 0
}
}
}
# Example usage:
# puts [RateLimiter::allow_request "user_1" 5 1000]
# Test cases
namespace eval RateLimiterTest {
namespace import ::tcltest::*
test allow_request_1 "Test first request is allowed" {
RateLimiter::allow_request "test_user" 3 1000
} -result 1
test allow_request_2 "Test multiple requests within limit" {
set res [list]
lappend res [RateLimiter::allow_request "test_user" 3 1000]
lappend res [RateLimiter::allow_request "test_user" 3 1000]
lappend res [RateLimiter::allow_request "test_user" 3 1000]
join $res ","
} -result "1,1,1"
test allow_request_3 "Test request exceeding limit is denied" {
set res [list]
lappend res [RateLimiter::allow_request "test_user" 3 1000]
lappend res [RateLimiter::allow_request "test_user" 3 1000]
lappend res [RateLimiter::allow_request "test_user" 3 1000]
lappend res [RateLimiter::allow_request "test_user" 3 1000]
join $res ","
} -result "1,1,1,0"
test allow_request_4 "Test rolling window allows new requests over time" {
set res [list]
lappend res [RateLimiter::allow_request "test_user" 3 1000]
lappend res [RateLimiter::allow_request "test_user" 3 1000]
lappend res [RateLimiter::allow_request "test_user" 3 1000]
after 1100
lappend res [RateLimiter::allow_request "test_user" 3 1000]
join $res ","
} -result "1,1,1,1"
test allow_request_5 "Test requests spread over multiple windows" {
set res [list]
lappend res [RateLimiter::allow_request "test_user" 3 1000]
after 500
lappend res [RateLimiter::allow_request "test_user" 3 1000]
after 500
lappend res [RateLimiter::allow_request "test_user" 3 1000]
after 1100
lappend res [RateLimiter::allow_request "test_user" 3 1000]
join $res ","
} -result "1,1,1,1"
}