[hw-5] concurrency, graceful shutdown, concurrent tests

This commit is contained in:
Никита Шубин
2025-07-06 20:52:27 +00:00
parent dbf8aaedcf
commit 84201fe495
23 changed files with 742 additions and 157 deletions

View File

@@ -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
}