Refactor gRPC adapter to use connection pool and improve error handling in product retrieval
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package products
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/samber/lo"
|
||||
"google.golang.org/grpc"
|
||||
pb "sipro-mps/api/generated/v1/ozon/products"
|
||||
@@ -26,20 +27,23 @@ func RegisterAdapterGRPC(server *grpc.Server, marketplaceRepo marketplace.Reposi
|
||||
pb.RegisterProductsServiceServer(server, adapter)
|
||||
return &apiRepo, nil
|
||||
}
|
||||
|
||||
func (g *AdapterGRPC) GetListOfProducts(req *pb.GetListOfProductsRequest, stream pb.ProductsService_GetListOfProductsServer) error {
|
||||
ctx := stream.Context()
|
||||
fmt.Printf("GetListOfProducts called with req: %+v\n", req.MarketplaceId)
|
||||
converter := generated.ConverterImpl{}
|
||||
resultChan := make(chan []OzonProduct)
|
||||
errChan := make(chan error)
|
||||
g.repo.StreamAllProducts(ctx, 262, resultChan, errChan)
|
||||
|
||||
go g.repo.StreamAllProducts(ctx, int(req.MarketplaceId), resultChan, errChan) // Запускаем в горутине
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err() // Handle context cancellation
|
||||
fmt.Println("GetListOfProducts: context cancelled or deadline exceeded:", ctx.Err())
|
||||
return ctx.Err()
|
||||
case products, ok := <-resultChan:
|
||||
if !ok {
|
||||
return nil
|
||||
return nil // Завершаем, только если результат закрыт
|
||||
}
|
||||
protoProducts := lo.Map(products, func(product OzonProduct, _ int) *pb.Product {
|
||||
return converter.ToProto(&product)
|
||||
@@ -48,13 +52,12 @@ func (g *AdapterGRPC) GetListOfProducts(req *pb.GetListOfProductsRequest, stream
|
||||
Products: protoProducts,
|
||||
}
|
||||
if err := stream.Send(resp); err != nil {
|
||||
return err // Error sending response
|
||||
fmt.Println("GetListOfProducts: error sending response:", err)
|
||||
return err
|
||||
}
|
||||
case err, ok := <-errChan:
|
||||
if !ok {
|
||||
return nil // Exit loop when errChan is closed
|
||||
}
|
||||
if err != nil {
|
||||
if ok && err != nil {
|
||||
fmt.Println("GetListOfProducts: error received from channel:", err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,8 +31,8 @@ func fetchProductIds(ctx context.Context, client *api.Client, resultChan chan<-
|
||||
})
|
||||
if err != nil {
|
||||
// dev
|
||||
panic(err)
|
||||
//errChan <- fmt.Errorf("fetching product IDs: %w", err)
|
||||
//panic(err)
|
||||
errChan <- fmt.Errorf("fetching product IDs: %w", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -65,8 +65,8 @@ func fetchProducts(ctx context.Context, client *api.Client, productIdsChan <-cha
|
||||
})
|
||||
if err != nil {
|
||||
// dev
|
||||
panic(err)
|
||||
//errChan <- fmt.Errorf("fetching products: %w", err)
|
||||
//panic(err)
|
||||
errChan <- fmt.Errorf("fetching products: %w", err)
|
||||
return
|
||||
}
|
||||
items := resp.Items
|
||||
|
||||
@@ -43,7 +43,6 @@ type RateLimitTransport struct {
|
||||
}
|
||||
|
||||
func (t *RateLimitTransport) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||
fmt.Println(time.Now().Format("2006-01-02 15:04:05"))
|
||||
ctx := req.Context()
|
||||
clientId := req.Header.Get("Client-Id")
|
||||
now := time.Now().UnixNano()
|
||||
@@ -57,6 +56,7 @@ func (t *RateLimitTransport) RoundTrip(req *http.Request) (*http.Response, error
|
||||
return nil, fmt.Errorf("failed to execute rate limit script: %w", err)
|
||||
}
|
||||
if waitTime > 0 {
|
||||
fmt.Printf("Rate limit exceeded for client %s, waiting for %d nanoseconds\n", clientId, waitTime)
|
||||
time.Sleep(time.Duration(waitTime))
|
||||
}
|
||||
return t.RoundTripper.RoundTrip(req)
|
||||
|
||||
Reference in New Issue
Block a user