Posted to tcl by apn at Sat Feb 01 16:43:23 GMT 2025view raw
- # 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"
- }
-