fix: prevent sessionHash collision for different users with same messages

Mix SessionContext (ClientIP, UserAgent, APIKeyID) into
GenerateSessionHash 3rd-level fallback to differentiate requests
from different users sending identical content.

Also switch hashContent from SHA256-truncated to XXHash64 for
better performance, and optimize Trie Lua script to match from
longest prefix first.
This commit is contained in:
erio
2026-02-09 06:46:32 +08:00
parent 0b8fea4cb4
commit 5c76b9e45a
6 changed files with 913 additions and 24 deletions

View File

@@ -19,25 +19,34 @@ const (
// ARGV[2] = TTL seconds (用于刷新)
// 返回: 最长匹配的 value (uuid:accountID) 或 nil
// 查找成功时自动刷新 TTL防止活跃会话意外过期
// 从最长前缀(完整 chain开始逐步缩短第一次命中即返回
geminiTrieFindScript = `
local chain = ARGV[1]
local ttl = tonumber(ARGV[2])
local lastMatch = nil
local path = ""
for part in string.gmatch(chain, "[^-]+") do
path = path == "" and part or path .. "-" .. part
local val = redis.call('HGET', KEYS[1], path)
-- 先尝试完整 chain最常见场景同一对话的下一轮请求
local val = redis.call('HGET', KEYS[1], chain)
if val and val ~= "" then
redis.call('EXPIRE', KEYS[1], ttl)
return val
end
-- 从最长前缀开始逐步缩短(去掉最后一个 "-xxx" 段)
local path = chain
while true do
local i = string.find(path, "-[^-]*$")
if not i or i <= 1 then
break
end
path = string.sub(path, 1, i - 1)
val = redis.call('HGET', KEYS[1], path)
if val and val ~= "" then
lastMatch = val
redis.call('EXPIRE', KEYS[1], ttl)
return val
end
end
if lastMatch then
redis.call('EXPIRE', KEYS[1], ttl)
end
return lastMatch
return nil
`
// geminiTrieSaveScript 保存会话到 Trie 的 Lua 脚本