MIF_E31222379_BE/internal/worker/cart_worker.go

77 lines
1.6 KiB
Go

package worker
import (
"log"
"strings"
"time"
"rijig/config"
"rijig/internal/services"
)
const (
lockPrefix = "lock:cart:"
lockExpiration = 30 * time.Second
commitThreshold = 20 * time.Second
scanPattern = "cart:*"
)
func StartCartCommitWorker(service *services.CartService) {
go func() {
ticker := time.NewTicker(10 * time.Second)
defer ticker.Stop()
log.Println("🛠️ Cart Worker is running in background...")
for range ticker.C {
processCarts(service)
}
}()
}
func processCarts(service *services.CartService) {
iter := config.RedisClient.Scan(config.Ctx, 0, scanPattern, 0).Iterator()
for iter.Next(config.Ctx) {
key := iter.Val()
ttl, err := config.RedisClient.TTL(config.Ctx, key).Result()
if err != nil {
log.Printf("❌ Error getting TTL for %s: %v", key, err)
continue
}
if ttl > 0 && ttl < commitThreshold {
userID := extractUserIDFromKey(key)
if userID == "" {
continue
}
lockKey := lockPrefix + userID
acquired, err := config.RedisClient.SetNX(config.Ctx, lockKey, "locked", lockExpiration).Result()
if err != nil || !acquired {
continue
}
log.Printf("🔄 Auto-committing cart for user %s (TTL: %v)", userID, ttl)
if err := service.CommitCartToDatabase(userID); err != nil {
log.Printf("❌ Failed to commit cart for %s: %v", userID, err)
} else {
log.Printf("✅ Cart committed for user %s", userID)
}
}
}
if err := iter.Err(); err != nil {
log.Printf("❌ Error iterating Redis keys: %v", err)
}
}
func extractUserIDFromKey(key string) string {
if strings.HasPrefix(key, "cart:") {
return strings.TrimPrefix(key, "cart:")
}
return ""
}