mirror of
				https://github.com/3ybactuk/marketplace-go-service-project.git
				synced 2025-10-31 06:23:44 +03:00 
			
		
		
		
	[hw-5] concurrency, graceful shutdown, concurrent tests
This commit is contained in:
		| @@ -10,23 +10,40 @@ import ( | ||||
| 
 | ||||
| 	"route256/cart/internal/domain/entity" | ||||
| 	"route256/cart/internal/domain/model" | ||||
| 	"route256/cart/internal/infra/errgroup" | ||||
| 
 | ||||
| 	"github.com/rs/zerolog/log" | ||||
| 	"golang.org/x/time/rate" | ||||
| ) | ||||
| 
 | ||||
| type ProductService struct { | ||||
| 	httpClient http.Client | ||||
| 	token      string | ||||
| 	address    string | ||||
| 
 | ||||
| 	limiter *rate.Limiter | ||||
| 
 | ||||
| 	workers int | ||||
| } | ||||
| 
 | ||||
| func NewProductService(httpClient http.Client, token string, address string) *ProductService { | ||||
| func NewProductService(httpClient http.Client, token, address string, limitRPS, burst, workers int) *ProductService { | ||||
| 	log.Debug().Msgf("creating product server with %d worker limit", workers) | ||||
| 
 | ||||
| 	return &ProductService{ | ||||
| 		httpClient: httpClient, | ||||
| 		token:      token, | ||||
| 		address:    address, | ||||
| 
 | ||||
| 		limiter: rate.NewLimiter(rate.Limit(limitRPS), burst), | ||||
| 		workers: workers, | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (s *ProductService) GetProductBySku(ctx context.Context, sku entity.Sku) (*model.Product, error) { | ||||
| 	if err := s.limiter.Wait(ctx); err != nil { | ||||
| 		return nil, fmt.Errorf("limiter.Wait: %w", err) | ||||
| 	} | ||||
| 
 | ||||
| 	ctx, cancel := context.WithTimeout(ctx, 5*time.Second) | ||||
| 	defer cancel() | ||||
| 
 | ||||
| @@ -73,3 +90,32 @@ type GetProductResponse struct { | ||||
| 	Price int32  `json:"price"` | ||||
| 	Sku   int64  `json:"sku"` | ||||
| } | ||||
| 
 | ||||
| func (s *ProductService) GetProducts(ctx context.Context, skus []entity.Sku) ([]*model.Product, error) { | ||||
| 	if len(skus) == 0 { | ||||
| 		return []*model.Product{}, nil | ||||
| 	} | ||||
| 
 | ||||
| 	results := make([]*model.Product, len(skus)) | ||||
| 
 | ||||
| 	g, _ := errgroup.WithContext(ctx, s.workers) | ||||
| 
 | ||||
| 	for i, sku := range skus { | ||||
| 		g.Go(func(groupCtx context.Context) error { | ||||
| 			p, err := s.GetProductBySku(groupCtx, sku) | ||||
| 			if err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 
 | ||||
| 			results[i] = p | ||||
| 
 | ||||
| 			return nil | ||||
| 		}) | ||||
| 	} | ||||
| 
 | ||||
| 	if err := g.Wait(); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	return results, nil | ||||
| } | ||||
		Reference in New Issue
	
	Block a user
	 Никита Шубин
					Никита Шубин