@@ -1051,16 +1051,44 @@ func (s *RateLimitService) UpdateSessionWindow(ctx context.Context, account *Acc
10511051 var windowStart , windowEnd * time.Time
10521052 needInitWindow := account .SessionWindowEnd == nil || time .Now ().After (* account .SessionWindowEnd )
10531053
1054- if needInitWindow && (status == "allowed" || status == "allowed_warning" ) {
1055- // 预测时间窗口:从当前时间的整点开始,+5小时为结束
1056- // 例如:现在是 14:30,窗口为 14:00 ~ 19:00
1054+ // 优先使用响应头中的真实重置时间(比预测更准确)
1055+ if resetStr := headers .Get ("anthropic-ratelimit-unified-5h-reset" ); resetStr != "" {
1056+ if ts , err := strconv .ParseInt (resetStr , 10 , 64 ); err == nil {
1057+ // 检测可能的毫秒时间戳(秒级约为 1e9,毫秒约为 1e12)
1058+ if ts > 1e11 {
1059+ slog .Warn ("account_session_window_header_millis_detected" , "account_id" , account .ID , "raw_reset" , resetStr )
1060+ ts = ts / 1000
1061+ }
1062+ end := time .Unix (ts , 0 )
1063+ // 校验时间戳是否在合理范围内(不早于 5h 前,不晚于 7 天后)
1064+ minAllowed := time .Now ().Add (- 5 * time .Hour )
1065+ maxAllowed := time .Now ().Add (7 * 24 * time .Hour )
1066+ if end .Before (minAllowed ) || end .After (maxAllowed ) {
1067+ slog .Warn ("account_session_window_header_out_of_range" , "account_id" , account .ID , "raw_reset" , resetStr , "parsed_end" , end )
1068+ } else if needInitWindow || account .SessionWindowEnd == nil || ! end .Equal (* account .SessionWindowEnd ) {
1069+ // 窗口需要初始化,或者真实重置时间与已存储的不同,则更新
1070+ start := end .Add (- 5 * time .Hour )
1071+ windowStart = & start
1072+ windowEnd = & end
1073+ slog .Info ("account_session_window_from_header" , "account_id" , account .ID , "window_start" , start , "window_end" , end , "status" , status )
1074+ }
1075+ } else {
1076+ slog .Warn ("account_session_window_header_parse_failed" , "account_id" , account .ID , "raw_reset" , resetStr , "error" , err )
1077+ }
1078+ }
1079+
1080+ // 回退:如果没有真实重置时间且需要初始化窗口,使用预测
1081+ if windowEnd == nil && needInitWindow && (status == "allowed" || status == "allowed_warning" ) {
10571082 now := time .Now ()
10581083 start := time .Date (now .Year (), now .Month (), now .Day (), now .Hour (), 0 , 0 , 0 , now .Location ())
10591084 end := start .Add (5 * time .Hour )
10601085 windowStart = & start
10611086 windowEnd = & end
10621087 slog .Info ("account_session_window_initialized" , "account_id" , account .ID , "window_start" , start , "window_end" , end , "status" , status )
1063- // 窗口重置时清除旧的 utilization,避免残留上个窗口的数据
1088+ }
1089+
1090+ // 窗口重置时清除旧的 utilization,避免残留上个窗口的数据
1091+ if windowEnd != nil && needInitWindow {
10641092 _ = s .accountRepo .UpdateExtra (ctx , account .ID , map [string ]any {
10651093 "session_window_utilization" : nil ,
10661094 })
0 commit comments