client.go 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. package internal
  2. import (
  3. "context"
  4. "fmt"
  5. "time"
  6. "zero/rpcx/internal/clientinterceptors"
  7. "google.golang.org/grpc"
  8. )
  9. const dialTimeout = time.Second * 3
  10. type (
  11. ClientOptions struct {
  12. Timeout time.Duration
  13. DialOptions []grpc.DialOption
  14. }
  15. ClientOption func(options *ClientOptions)
  16. Client interface {
  17. Next() (*grpc.ClientConn, bool)
  18. }
  19. )
  20. func WithDialOption(opt grpc.DialOption) ClientOption {
  21. return func(options *ClientOptions) {
  22. options.DialOptions = append(options.DialOptions, opt)
  23. }
  24. }
  25. func WithTimeout(timeout time.Duration) ClientOption {
  26. return func(options *ClientOptions) {
  27. options.Timeout = timeout
  28. }
  29. }
  30. func buildDialOptions(opts ...ClientOption) []grpc.DialOption {
  31. var clientOptions ClientOptions
  32. for _, opt := range opts {
  33. opt(&clientOptions)
  34. }
  35. options := []grpc.DialOption{
  36. grpc.WithInsecure(),
  37. grpc.WithBlock(),
  38. WithUnaryClientInterceptors(
  39. clientinterceptors.BreakerInterceptor,
  40. clientinterceptors.DurationInterceptor,
  41. clientinterceptors.PromMetricInterceptor,
  42. clientinterceptors.TimeoutInterceptor(clientOptions.Timeout),
  43. clientinterceptors.TracingInterceptor,
  44. ),
  45. }
  46. return append(options, clientOptions.DialOptions...)
  47. }
  48. func dial(server string, opts ...ClientOption) (*grpc.ClientConn, error) {
  49. options := buildDialOptions(opts...)
  50. timeCtx, cancel := context.WithTimeout(context.Background(), dialTimeout)
  51. defer cancel()
  52. conn, err := grpc.DialContext(timeCtx, server, options...)
  53. if err != nil {
  54. return nil, fmt.Errorf("rpc dial: %s, error: %s", server, err.Error())
  55. }
  56. return conn, nil
  57. }