feat: implement locking mechanism for marketplace operations to prevent race conditions
This commit is contained in:
		@@ -101,6 +101,7 @@ func fetchProducts(
 | 
			
		||||
func (a apiRepository) StreamAllProductsCache(ctx context.Context, marketplaceId int, resultChan chan<- []pb.Product, errChan chan<- error) {
 | 
			
		||||
	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)
 | 
			
		||||
@@ -111,9 +112,7 @@ func (a apiRepository) StreamAllProductsCache(ctx context.Context, marketplaceId
 | 
			
		||||
		errChan <- fmt.Errorf("getting marketplace identifier: %w", err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	converter := generated.ConverterImpl{}
 | 
			
		||||
 | 
			
		||||
	key := GetProductsKey(identifier)
 | 
			
		||||
	var cachedMessage pb.GetProductsResponse
 | 
			
		||||
	err = redis.ReadProtoMessage(ctx, key, &cachedMessage)
 | 
			
		||||
@@ -122,6 +121,12 @@ func (a apiRepository) StreamAllProductsCache(ctx context.Context, marketplaceId
 | 
			
		||||
		_ = client.EnqueueFetchProductsTask(types.TypeWbFetchProducts, marketplaceId)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	locker := *redis.Locker
 | 
			
		||||
	_, cancel, err := locker.TryWithContext(ctx, fmt.Sprintf("wb:products:marketplace:%s:lock", key))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	defer cancel()
 | 
			
		||||
 | 
			
		||||
	innerResultChan := make(chan []WbProduct)
 | 
			
		||||
	innerErrChan := make(chan error)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user