commit dfe0b10: [Minor] Clickhouse: Try to deal with clock skew in retention logic

Vsevolod Stakhov vsevolod at highsecure.ru
Wed Oct 27 20:07:04 UTC 2021


Author: Vsevolod Stakhov
Date: 2021-10-27 21:02:38 +0100
URL: https://github.com/rspamd/rspamd/commit/dfe0b1009756bfc91609e95de2923a6e59bf7a2d (HEAD -> master)

[Minor] Clickhouse: Try to deal with clock skew in retention logic

---
 src/plugins/lua/clickhouse.lua | 38 +++++++++++++++++++++++++-------------
 1 file changed, 25 insertions(+), 13 deletions(-)

diff --git a/src/plugins/lua/clickhouse.lua b/src/plugins/lua/clickhouse.lua
index 130ee9d1e..97c66946d 100644
--- a/src/plugins/lua/clickhouse.lua
+++ b/src/plugins/lua/clickhouse.lua
@@ -958,21 +958,11 @@ end
 ]]
 local function get_last_removal_ago()
   local ts_file = string.format('%s/%s', rspamd_paths['DBDIR'], 'clickhouse_retention_run')
-  local f, err = io.open(ts_file, 'r')
-  local write_file
   local last_ts
-
-  if err then
-    lua_util.debugm(N, rspamd_config, 'Failed to open %s: %s', ts_file, err)
-  else
-    last_ts = tonumber(f:read('*number'))
-    f:close()
-  end
-
   local current_ts = os.time()
 
-  if last_ts == nil or (last_ts + settings.retention.period) <= current_ts then
-    write_file, err = io.open(ts_file, 'w')
+  local function write_ts_to_file()
+    local write_file, err = io.open(ts_file, 'w')
     if err then
       rspamd_logger.errx(rspamd_config, 'Failed to open %s, will not perform retention: %s', ts_file, err)
       return nil
@@ -981,11 +971,33 @@ local function get_last_removal_ago()
     local res
     res, err = write_file:write(tostring(current_ts))
     if err or res == nil then
+      write_file:close()
       rspamd_logger.errx(rspamd_config, 'Failed to write %s, will not perform retention: %s', ts_file, err)
       return nil
     end
     write_file:close()
-    return 0
+
+    return true
+  end
+
+  local f, err = io.open(ts_file, 'r')
+  if err then
+    lua_util.debugm(N, rspamd_config, 'Failed to open %s: %s', ts_file, err)
+  else
+    last_ts = tonumber(f:read('*number'))
+    f:close()
+  end
+
+  if last_ts > current_ts then
+    -- Clock skew detected, overwrite last_ts with current_ts and wait for the next
+    -- retention period
+    rspamd_logger.errx(rspamd_config, 'Last collection time is in future: %s; overwrite it with %s in %s',
+        last_ts, current_ts, ts_file)
+    return write_ts_to_file() and -1
+  end
+
+  if last_ts == nil or (last_ts + settings.retention.period) <= current_ts then
+    return write_ts_to_file() and 0
   end
 
   return (last_ts + settings.retention.period) - current_ts


More information about the Commits mailing list