package wb import ( "context" "encoding/json" "fmt" pb "sipro-mps/api/generated/v1/wb/products" "sipro-mps/internal/marketplace" "sipro-mps/internal/redis" "sipro-mps/internal/tasks/types" "sipro-mps/internal/wb/products" "sipro-mps/internal/wb/products/mapping/generated" "github.com/hibiken/asynq" "github.com/jackc/pgx/v5/pgxpool" "github.com/samber/lo" ) type FetchProductsProcessor struct { Dbpool *pgxpool.Pool } 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.RevokeTask } marketplaceRepo := marketplace.NewDBRepository(p.Dbpool) repo := products.NewAPIRepository(marketplaceRepo) marketplaceById, err := marketplaceRepo.GetMarketplaceByID(ctx, payload.MarketplaceId) if err != nil { return fmt.Errorf("failed to get marketplace by ID %d: %w", payload.MarketplaceId, err) } sellerId, err := marketplaceById.GetIdentifier() if err != nil { return fmt.Errorf("failed to get identifier for 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.RevokeTask } 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 := generated.ConverterImpl{} productsProto := lo.Map(productsRaw, func(item products.WbProduct, _ int) *pb.Product { return converter.ToProto(&item) }) err = redis.WriteProtoMessage(ctx, redisKey, &pb.GetProductsResponse{Products: productsProto}) if err != nil { fmt.Printf( "Failed to write products to Redis for marketplace %s: %v\n") return asynq.RevokeTask } return nil }