fix(backend): 修复代码审核发现的 8 个确认问题
- P0-1: subscription_maintenance_queue 使用 RWMutex 防止 channel close/send 竞态 - P0-2: billing_service CalculateCostWithLongContext 修复被吞没的 out-range 错误 - P1-1: timing_wheel_service Schedule/ScheduleRecurring 添加 SetTimer 错误日志 - P1-2: sora_gateway_service StoreFromURLs 失败时降级使用原始 URL - P1-3: concurrency_cache 用 Pipeline 替代 Lua 脚本兼容 Redis Cluster - P1-6: sora_media_cleanup_service runCleanup 添加 nil cfg/storage 防护 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -6,12 +6,14 @@ import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
// SubscriptionMaintenanceQueue 提供“有界队列 + 固定 worker”的后台执行器。
|
||||
// SubscriptionMaintenanceQueue 提供"有界队列 + 固定 worker"的后台执行器。
|
||||
// 用于从请求热路径触发维护动作时,避免无限 goroutine 膨胀。
|
||||
type SubscriptionMaintenanceQueue struct {
|
||||
queue chan func()
|
||||
wg sync.WaitGroup
|
||||
stop sync.Once
|
||||
queue chan func()
|
||||
wg sync.WaitGroup
|
||||
stop sync.Once
|
||||
mu sync.RWMutex // 保护 closed 标志与 channel 操作的原子性
|
||||
closed bool
|
||||
}
|
||||
|
||||
func NewSubscriptionMaintenanceQueue(workerCount, queueSize int) *SubscriptionMaintenanceQueue {
|
||||
@@ -48,6 +50,7 @@ func NewSubscriptionMaintenanceQueue(workerCount, queueSize int) *SubscriptionMa
|
||||
|
||||
// TryEnqueue 尝试将任务入队。
|
||||
// 当队列已满时返回 error(调用方应该选择跳过并记录告警/限频日志)。
|
||||
// 当队列已关闭时返回 error,不会 panic。
|
||||
func (q *SubscriptionMaintenanceQueue) TryEnqueue(task func()) error {
|
||||
if q == nil {
|
||||
return fmt.Errorf("maintenance queue is nil")
|
||||
@@ -56,6 +59,13 @@ func (q *SubscriptionMaintenanceQueue) TryEnqueue(task func()) error {
|
||||
return fmt.Errorf("maintenance task is nil")
|
||||
}
|
||||
|
||||
q.mu.RLock()
|
||||
defer q.mu.RUnlock()
|
||||
|
||||
if q.closed {
|
||||
return fmt.Errorf("maintenance queue stopped")
|
||||
}
|
||||
|
||||
select {
|
||||
case q.queue <- task:
|
||||
return nil
|
||||
@@ -69,7 +79,10 @@ func (q *SubscriptionMaintenanceQueue) Stop() {
|
||||
return
|
||||
}
|
||||
q.stop.Do(func() {
|
||||
q.mu.Lock()
|
||||
q.closed = true
|
||||
close(q.queue)
|
||||
q.mu.Unlock()
|
||||
q.wg.Wait()
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user