diff --git a/internal/ozon/products/repository_api.go b/internal/ozon/products/repository_api.go index a7ced8f..e837765 100644 --- a/internal/ozon/products/repository_api.go +++ b/internal/ozon/products/repository_api.go @@ -199,27 +199,7 @@ func (a *apiRepository) StreamProductAttributesCache(ctx context.Context, market errChan <- err return } - identifider, err := mp.GetIdentifier() - if err != nil { - errChan <- fmt.Errorf("getting marketplace identifier: %w", err) - return - } - key := fmt.Sprintf("ozon:products:attributes:%s", identifider) - var cachedMessage pb.GetProductAttributesResponse - err = redis.ReadProtoMessage(ctx, key, &cachedMessage) - if err == nil && len(cachedMessage.Items) > 0 { - resultChan <- utils.DerefSlice(cachedMessage.Items) - return - } converter := generated.ConverterImpl{} - var allAttributes []PbProductAttributes - defer func() { - if len(allAttributes) == 0 { - return - } - message := pb.GetProductAttributesResponse{Items: utils.ToPtrs(allAttributes)} - _ = redis.WriteProtoMessage(ctx, key, &message) - }() for _, chunk := range lo.Chunk(productIds, 1000) { chunkStrings := lo.Map(chunk, func(item int, index int) string { @@ -241,10 +221,7 @@ func (a *apiRepository) StreamProductAttributesCache(ctx context.Context, market return *converter.AttributesToProto(&item) }) resultChan <- attrs - allAttributes = append(allAttributes, attrs...) - } - //ozonClient.Products().GetDescriptionOfProducts() } func (a *apiRepository) DeleteProducts(ctx context.Context, marketplaceId int, items []*PbDeleteProductRequestItem) ([]*PbDeleteProductResponseItem, error) { diff --git a/internal/wb/products/repository_api.go b/internal/wb/products/repository_api.go index b0e2980..a44b7a3 100644 --- a/internal/wb/products/repository_api.go +++ b/internal/wb/products/repository_api.go @@ -95,7 +95,8 @@ func fetchProducts( } func (a apiRepository) StreamAllProductsCache(ctx context.Context, marketplaceId int, resultChan chan<- []pb.Product, errChan chan<- error) { - // DO NOT close channels here - WithCache will handle it (caller/creator owns them) + defer close(resultChan) + defer close(errChan) mp, err := a.marketplaceRepository.GetMarketplaceByID(ctx, marketplaceId) if err != nil { errChan <- fmt.Errorf("getting marketplace by ID: %w", err) diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go index 78f3eb6..7430313 100644 --- a/pkg/utils/utils.go +++ b/pkg/utils/utils.go @@ -1,8 +1,11 @@ package utils import ( + "encoding/binary" "encoding/json" "fmt" + "hash/fnv" + "math" "github.com/golang-jwt/jwt/v5" ) @@ -49,3 +52,74 @@ func DerefSlice[T any](s []*T) []T { } return res } + +type Hashable interface { + ~int | ~int8 | ~int16 | ~int32 | ~int64 | + ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | + ~string | ~bool | ~float32 | ~float64 +} + +func HashArray[T Hashable](arr []T) (string, error) { + h := fnv.New64a() + buf := make([]byte, 8) + + for _, v := range arr { + var b []byte + + switch val := any(v).(type) { + case int: + binary.LittleEndian.PutUint64(buf, uint64(val)) + b = buf + case int8: + buf[0] = byte(val) + b = buf[:1] + case int16: + binary.LittleEndian.PutUint16(buf, uint16(val)) + b = buf[:2] + case int32: + binary.LittleEndian.PutUint32(buf, uint32(val)) + b = buf[:4] + case int64: + binary.LittleEndian.PutUint64(buf, uint64(val)) + b = buf + case uint: + binary.LittleEndian.PutUint64(buf, uint64(val)) + b = buf + case uint8: + buf[0] = val + b = buf[:1] + case uint16: + binary.LittleEndian.PutUint16(buf, val) + b = buf[:2] + case uint32: + binary.LittleEndian.PutUint32(buf, val) + b = buf[:4] + case uint64: + binary.LittleEndian.PutUint64(buf, val) + b = buf + case float32: + binary.LittleEndian.PutUint32(buf[:4], math.Float32bits(val)) + b = buf[:4] + case float64: + binary.LittleEndian.PutUint64(buf, math.Float64bits(val)) + b = buf + case bool: + if val { + buf[0] = 1 + } else { + buf[0] = 0 + } + b = buf[:1] + case string: + b = []byte(val) + default: + return "", fmt.Errorf("unsupported type: %T", val) + } + + if _, err := h.Write(b); err != nil { + return "", fmt.Errorf("failed to write to hash: %w", err) + } + } + + return fmt.Sprintf("%x", h.Sum64()), nil +}