timeoutinterceptor.go 1.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. package clientinterceptors
  2. import (
  3. "context"
  4. "time"
  5. "google.golang.org/grpc"
  6. )
  7. // TimeoutInterceptor is an interceptor that controls timeout.
  8. func TimeoutInterceptor(timeout time.Duration) grpc.UnaryClientInterceptor {
  9. return func(ctx context.Context, method string, req, reply any, cc *grpc.ClientConn,
  10. invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
  11. t := getTimeoutByCallOptions(opts, timeout)
  12. if t <= 0 {
  13. return invoker(ctx, method, req, reply, cc, opts...)
  14. }
  15. ctx, cancel := context.WithTimeout(ctx, t)
  16. defer cancel()
  17. return invoker(ctx, method, req, reply, cc, opts...)
  18. }
  19. }
  20. func getTimeoutByCallOptions(callOptions []grpc.CallOption, defaultTimeout time.Duration) time.Duration {
  21. for _, callOption := range callOptions {
  22. if o, ok := callOption.(TimeoutCallOption); ok {
  23. return o.timeout
  24. }
  25. }
  26. return defaultTimeout
  27. }
  28. type TimeoutCallOption struct {
  29. grpc.EmptyCallOption
  30. timeout time.Duration
  31. }
  32. func WithTimeoutCallOption(timeout time.Duration) grpc.CallOption {
  33. return TimeoutCallOption{
  34. timeout: timeout,
  35. }
  36. }