fix: harden queue retries and quota reservation

This commit is contained in:
237899745
2026-07-25 18:15:39 +08:00
parent 091a0cee75
commit f389dfb567
9 changed files with 358 additions and 101 deletions

View File

@@ -306,6 +306,46 @@ pub async fn consume_anonymous_units(
Ok(())
}
pub async fn refund_anonymous_units(
state: &AppState,
session_id: &str,
ip: IpAddr,
units: u32,
) -> Result<(), AppError> {
if units == 0 {
return Ok(());
}
let date = utc8_date();
let session_key = format!("anon_quota:{session_id}:{date}");
let ip_key = format!("anon_quota_ip:{ip}:{date}");
let mut conn = state.redis.clone();
let script = redis::Script::new(
r#"
local dec = tonumber(ARGV[1])
local function refund(key)
local current = tonumber(redis.call('GET', key) or '0')
if current <= 0 then return 0 end
return redis.call('DECRBY', key, math.min(current, dec))
end
refund(KEYS[1])
refund(KEYS[2])
return 1
"#,
);
let _: i64 = script
.key(session_key)
.key(ip_key)
.arg(units as i64)
.invoke_async(&mut conn)
.await
.map_err(|err| AppError::new(ErrorCode::Internal, "退还匿名配额失败").with_source(err))?;
Ok(())
}
fn utc8_date() -> String {
let now = Utc::now() + Duration::hours(8);
now.format("%Y-%m-%d").to_string()