]> source.dussan.org Git - rspamd.git/commitdiff
[Feature] Add LRU cache for last filled ratelimit buckets
authorLeftTry <lerest.go@gmail.com>
Sun, 29 Sep 2024 06:23:46 +0000 (12:23 +0600)
committerLeftTry <lerest.go@gmail.com>
Sun, 29 Sep 2024 06:23:46 +0000 (12:23 +0600)
lualib/redis_scripts/ratelimit_check.lua
src/plugins/lua/ratelimit.lua

index f24e0daf0c88d98114eb59aaa1b825bb98404865..f066610a54c420564ce28e636cabc9e936c3cdcc 100644 (file)
@@ -31,6 +31,8 @@ local leak_rate = tonumber(KEYS[3])
 local max_burst = tonumber(KEYS[4])
 local prefix = KEYS[1]
 local enable_dynamic = KEYS[7] == 'true'
+local cache_prefix = KEYS[8]
+local max_cache_size = KEYS[9]
 local dynr, dynb, leaked = 0, 0, 0
 if not last then
   -- New bucket
@@ -83,6 +85,9 @@ if burst + pending > 0 then
 
   burst = burst + pending
   if burst > 0 and burst > max_burst * dynb then
+    redis.call('ZREMRANGEBYRANK', cache_prefix, 0, -(max_cache_size + 1))
+    redis.call('ZINCRBY', cache_prefix, 1, prefix)
+
     return { 1, tostring(burst - pending), tostring(dynr), tostring(dynb), tostring(leaked) }
   end
   -- Increase pending if we allow ratelimit
index 168d8d63ae35208a8652f33a29c1e7ca22731102..c0783eac8ed786643980e4de49b05039fd206470 100644 (file)
@@ -41,6 +41,8 @@ local settings = {
   -- Do not check ratelimits for these recipients
   whitelisted_rcpts = { 'postmaster', 'mailer-daemon' },
   prefix = 'RL',
+  cache_prefix = 'RL_cache_prefix',
+  max_cache_size = 30,
   -- If enabled, we apply dynamic rate limiting based on the verdict
   dynamic_rate_limit = false,
   ham_factor_rate = 1.01,
@@ -455,7 +457,8 @@ local function ratelimit_cb(task)
           { key = value.hash, task = task, is_write = true },
           gen_check_cb(pr, bucket, value.name, value.hash),
           { value.hash, tostring(now), tostring(rate), tostring(bucket.burst),
-            tostring(settings.expire), tostring(bincr), tostring(dyn_rate_enabled) })
+            tostring(settings.expire), tostring(bincr), tostring(dyn_rate_enabled),
+            settings.cache_prefix, settings.max_cache_size })
     end
   end
 end