package wb import ( "context" "encoding/json" "fmt" "github.com/hibiken/asynq" "github.com/jackc/pgx/v5/pgxpool" "github.com/samber/lo" pb "sipro-mps/api/generated/v1/wb/products" mp_repo "sipro-mps/internal/marketplace" "sipro-mps/internal/redis" "sipro-mps/internal/tasks/types" wb_products_repo "sipro-mps/internal/wb/products" conv "sipro-mps/internal/wb/products/mapping/generated" ) type FetchProductsProcessor struct { Dbpool *pgxpool.Pool wbRepo wb_products_repo.Repository } func (p *FetchProductsProcessor) ProcessTask(ctx context.Context, task *asynq.Task) error { var payload types.FetchProductsTask if err := json.Unmarshal(task.Payload(), &payload); err != nil { return asynq.SkipRetry } marketplaceRepo := mp_repo.NewDBRepository(p.Dbpool) repo := wb_products_repo.NewAPIRepository(marketplaceRepo) _, sellerId, err := repo.ParseMarketplace(ctx, payload.MarketplaceId) if err != nil { return fmt.Errorf("failed to parse marketplace %d: %w", payload.MarketplaceId, err) } locker := *redis.Locker _, cancel, err := locker.TryWithContext(ctx, fmt.Sprintf("wb:products:marketplace:%s:lock", sellerId)) if err != nil { fmt.Printf("Failed to acquire lock for marketplace %s: %v\n", sellerId, err) return asynq.SkipRetry } fmt.Println("Working on marketplace", payload.MarketplaceId, "with seller ID", sellerId) defer cancel() redisKey := fmt.Sprintf("wb:products:%s", sellerId) productsRaw, err := repo.GetAllProducts(ctx, payload.MarketplaceId) if err != nil { return fmt.Errorf("failed to fetch products for marketplace %d: %w", payload.MarketplaceId, err) } converter := conv.ConverterImpl{} products := lo.Map(productsRaw, func(item wb_products_repo.WbProduct, _ int) *pb.Product { return converter.ToProto(&item) }) redisClient := *redis.Client productsJson, err := json.Marshal(products) if err != nil { return fmt.Errorf("failed to marshal products: %w", err) } err = redisClient.Do(ctx, redisClient.B().Set().Key(redisKey).Value(string(productsJson)).Build()).Error() if err != nil { return err } return nil }