NewClient constructs a new Client.
(httpClient HTTPClient, url string, options ...ClientOption)
| 40 | |
| 41 | // NewClient constructs a new Client. |
| 42 | func NewClient[Req, Res any](httpClient HTTPClient, url string, options ...ClientOption) *Client[Req, Res] { |
| 43 | client := &Client[Req, Res]{} |
| 44 | config, err := newClientConfig(url, options) |
| 45 | if err != nil { |
| 46 | client.err = err |
| 47 | return client |
| 48 | } |
| 49 | client.config = config |
| 50 | protocolClient, protocolErr := client.config.Protocol.NewClient( |
| 51 | &protocolClientParams{ |
| 52 | CompressionName: config.RequestCompressionName, |
| 53 | CompressionPools: newReadOnlyCompressionPools( |
| 54 | config.CompressionPools, |
| 55 | config.CompressionNames, |
| 56 | ), |
| 57 | Codec: config.Codec, |
| 58 | Protobuf: config.protobuf(), |
| 59 | CompressMinBytes: config.CompressMinBytes, |
| 60 | HTTPClient: httpClient, |
| 61 | URL: config.URL, |
| 62 | BufferPool: config.BufferPool, |
| 63 | ReadMaxBytes: config.ReadMaxBytes, |
| 64 | SendMaxBytes: config.SendMaxBytes, |
| 65 | EnableGet: config.EnableGet, |
| 66 | GetURLMaxBytes: config.GetURLMaxBytes, |
| 67 | GetUseFallback: config.GetUseFallback, |
| 68 | }, |
| 69 | ) |
| 70 | if protocolErr != nil { |
| 71 | client.err = protocolErr |
| 72 | return client |
| 73 | } |
| 74 | client.protocolClient = protocolClient |
| 75 | // Rather than applying unary interceptors along the hot path, we can do it |
| 76 | // once at client creation. |
| 77 | unarySpec := config.newSpec(StreamTypeUnary) |
| 78 | unaryFunc := UnaryFunc(func(ctx context.Context, request AnyRequest) (AnyResponse, error) { |
| 79 | conn := client.protocolClient.NewConn(ctx, unarySpec, request.Header()) |
| 80 | conn.onRequestSend(func(r *http.Request) { |
| 81 | request.setRequestMethod(r.Method) |
| 82 | callInfo, ok := clientCallInfoForContext(ctx) |
| 83 | if ok { |
| 84 | callInfo.method = r.Method |
| 85 | callInfo.responseSource = conn |
| 86 | } |
| 87 | }) |
| 88 | // Send always returns an io.EOF unless the error is from the client-side. |
| 89 | // We want the user to continue to call Receive in those cases to get the |
| 90 | // full error from the server-side. |
| 91 | if err := conn.Send(request.Any()); err != nil && !errors.Is(err, io.EOF) { |
| 92 | _ = conn.CloseRequest() |
| 93 | _ = conn.CloseResponse() |
| 94 | return nil, err |
| 95 | } |
| 96 | if err := conn.CloseRequest(); err != nil { |
| 97 | _ = conn.CloseResponse() |
| 98 | return nil, err |
| 99 | } |