github.com/grafana/pyroscope@v1.18.0/pkg/util/circuitbreaker/cirquit_breaker.go (about)

     1  package circuitbreaker
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  
     7  	"github.com/pkg/errors"
     8  	"github.com/sony/gobreaker/v2"
     9  	"google.golang.org/grpc"
    10  	"google.golang.org/grpc/codes"
    11  	"google.golang.org/grpc/status"
    12  )
    13  
    14  func UnaryClientInterceptor(cb *gobreaker.CircuitBreaker[any]) grpc.UnaryClientInterceptor {
    15  	return func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
    16  		_, err := cb.Execute(func() (interface{}, error) {
    17  			return nil, invoker(ctx, method, req, reply, cc, opts...)
    18  		})
    19  		switch {
    20  		case err == nil:
    21  			return nil
    22  		case errors.Is(err, gobreaker.ErrOpenState) || errors.Is(err, gobreaker.ErrTooManyRequests):
    23  			return status.Error(codes.Unavailable, fmt.Sprintf("circuit breaker: %s", err.Error()))
    24  		default:
    25  			return err
    26  		}
    27  	}
    28  }