mirror of
https://github.com/3ybactuk/marketplace-go-service-project.git
synced 2025-12-21 10:19:04 +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