Files
sub2api/backend/internal/service/deferred_service.go
huangzhenpc d274c8cb14
Some checks failed
CI / test (push) Has been cancelled
CI / golangci-lint (push) Has been cancelled
feat: 品牌重命名 Sub2API -> TianShuAPI
- 前端: 所有界面显示、i18n 文本、组件中的品牌名称
- 后端: 服务层、设置默认值、邮件模板、安装向导
- 数据库: 迁移脚本注释
- 保持功能完全一致,仅更改品牌名称

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-04 17:50:29 +08:00

77 lines
1.9 KiB
Go

package service
import (
"context"
"log"
"sync"
"time"
)
// DeferredService provides deferred batch update functionality
type DeferredService struct {
accountRepo AccountRepository
timingWheel *TimingWheelService
interval time.Duration
lastUsedUpdates sync.Map
}
// NewDeferredService creates a new DeferredService instance
func NewDeferredService(accountRepo AccountRepository, timingWheel *TimingWheelService, interval time.Duration) *DeferredService {
return &DeferredService{
accountRepo: accountRepo,
timingWheel: timingWheel,
interval: interval,
}
}
// Start starts the deferred service
func (s *DeferredService) Start() {
s.timingWheel.ScheduleRecurring("deferred:last_used", s.interval, s.flushLastUsed)
log.Printf("[DeferredService] Started (interval: %v)", s.interval)
}
// Stop stops the deferred service
func (s *DeferredService) Stop() {
s.timingWheel.Cancel("deferred:last_used")
s.flushLastUsed()
log.Printf("[DeferredService] Service stopped")
}
func (s *DeferredService) ScheduleLastUsedUpdate(accountID int64) {
s.lastUsedUpdates.Store(accountID, time.Now())
}
func (s *DeferredService) flushLastUsed() {
updates := make(map[int64]time.Time)
s.lastUsedUpdates.Range(func(key, value any) bool {
id, ok := key.(int64)
if !ok {
return true
}
ts, ok := value.(time.Time)
if !ok {
return true
}
updates[id] = ts
s.lastUsedUpdates.Delete(key)
return true
})
if len(updates) == 0 {
return
}
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
if err := s.accountRepo.BatchUpdateLastUsed(ctx, updates); err != nil {
log.Printf("[DeferredService] BatchUpdateLastUsed failed (%d accounts): %v", len(updates), err)
for id, ts := range updates {
s.lastUsedUpdates.Store(id, ts)
}
} else {
log.Printf("[DeferredService] BatchUpdateLastUsed flushed %d accounts", len(updates))
}
}