Posted to tcl by apn at Sat Feb 01 16:43:23 GMT 2025view raw

  1. # Code generated by ChatGPT
  2. package require Tcl 8.6
  3. package require tcltest
  4.  
  5. namespace eval RateLimiter {
  6. variable limits
  7. array set limits {}
  8.  
  9. proc allow_request {key max_requests time_window} {
  10. variable limits
  11. set now [clock milliseconds]
  12.  
  13. if {![info exists limits($key)]} {
  14. set limits($key) "$max_requests $now"
  15. }
  16.  
  17. lassign $limits($key) tokens last_time
  18.  
  19. set elapsed [expr {$now - $last_time}]
  20. set new_tokens [expr {int($elapsed / $time_window) * $max_requests}]
  21.  
  22. set tokens [expr {min($tokens + $new_tokens, $max_requests)}]
  23. set last_time [expr {$now - ($elapsed % $time_window)}]
  24.  
  25. if {$tokens > 0} {
  26. set tokens [expr {$tokens - 1}]
  27. set limits($key) "$tokens $last_time"
  28. return 1
  29. } else {
  30. return 0
  31. }
  32. }
  33. }
  34.  
  35. # Example usage:
  36. # puts [RateLimiter::allow_request "user_1" 5 1000]
  37.  
  38. # Test cases
  39. namespace eval RateLimiterTest {
  40. namespace import ::tcltest::*
  41.  
  42. test allow_request_1 "Test first request is allowed" {
  43. RateLimiter::allow_request "test_user" 3 1000
  44. } -result 1
  45.  
  46. test allow_request_2 "Test multiple requests within limit" {
  47. set res [list]
  48. lappend res [RateLimiter::allow_request "test_user" 3 1000]
  49. lappend res [RateLimiter::allow_request "test_user" 3 1000]
  50. lappend res [RateLimiter::allow_request "test_user" 3 1000]
  51. join $res ","
  52. } -result "1,1,1"
  53.  
  54. test allow_request_3 "Test request exceeding limit is denied" {
  55. set res [list]
  56. lappend res [RateLimiter::allow_request "test_user" 3 1000]
  57. lappend res [RateLimiter::allow_request "test_user" 3 1000]
  58. lappend res [RateLimiter::allow_request "test_user" 3 1000]
  59. lappend res [RateLimiter::allow_request "test_user" 3 1000]
  60. join $res ","
  61. } -result "1,1,1,0"
  62.  
  63. test allow_request_4 "Test rolling window allows new requests over time" {
  64. set res [list]
  65. lappend res [RateLimiter::allow_request "test_user" 3 1000]
  66. lappend res [RateLimiter::allow_request "test_user" 3 1000]
  67. lappend res [RateLimiter::allow_request "test_user" 3 1000]
  68. after 1100
  69. lappend res [RateLimiter::allow_request "test_user" 3 1000]
  70. join $res ","
  71. } -result "1,1,1,1"
  72.  
  73. test allow_request_5 "Test requests spread over multiple windows" {
  74. set res [list]
  75. lappend res [RateLimiter::allow_request "test_user" 3 1000]
  76. after 500
  77. lappend res [RateLimiter::allow_request "test_user" 3 1000]
  78. after 500
  79. lappend res [RateLimiter::allow_request "test_user" 3 1000]
  80. after 1100
  81. lappend res [RateLimiter::allow_request "test_user" 3 1000]
  82. join $res ","
  83. } -result "1,1,1,1"
  84. }
  85.  

Add a comment

Please note that this site uses the meta tags nofollow,noindex for all pages that contain comments.
Items are closed for new comments after 1 week