diff options
author | Yuxuan 'fishy' Wang <yuxuan.wang@reddit.com> | 2021-01-22 09:37:18 -0800 |
---|---|---|
committer | Yuxuan 'fishy' Wang <fishywang@gmail.com> | 2021-01-22 20:50:27 -0800 |
commit | c2ddaf0766499ab522cb7c0ca011d579707fcb5f (patch) | |
tree | c05776669d220308884aa1fde25980035de056ad /lib | |
parent | 8dd04f4adfaea08699b1745c79f122bf9cbd6f07 (diff) | |
download | thrift-c2ddaf0766499ab522cb7c0ca011d579707fcb5f.tar.gz |
THRIFT-4914: Make TClient.Call to return the response meta
Client: go
Make a breaking change so that TClient.Call returns the response
meta, currently only contains headers but could be expanded in the
future, and make a compiler change to compiler generated clients to take
advantage of that and provide access to response metadata to users.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/go/thrift/client.go | 24 | ||||
-rw-r--r-- | lib/go/thrift/example_client_middleware_test.go | 6 | ||||
-rw-r--r-- | lib/go/thrift/header_protocol.go | 14 | ||||
-rw-r--r-- | lib/go/thrift/middleware.go | 4 | ||||
-rw-r--r-- | lib/go/thrift/middleware_test.go | 6 |
5 files changed, 27 insertions, 27 deletions
diff --git a/lib/go/thrift/client.go b/lib/go/thrift/client.go index 1c5705d55..ea2c01fda 100644 --- a/lib/go/thrift/client.go +++ b/lib/go/thrift/client.go @@ -5,8 +5,15 @@ import ( "fmt" ) +// ResponseMeta represents the metadata attached to the response. +type ResponseMeta struct { + // The headers in the response, if any. + // If the underlying transport/protocol is not THeader, this will always be nil. + Headers THeaderMap +} + type TClient interface { - Call(ctx context.Context, method string, args, result TStruct) error + Call(ctx context.Context, method string, args, result TStruct) (ResponseMeta, error) } type TStandardClient struct { @@ -78,18 +85,25 @@ func (p *TStandardClient) Recv(ctx context.Context, iprot TProtocol, seqId int32 return iprot.ReadMessageEnd(ctx) } -func (p *TStandardClient) Call(ctx context.Context, method string, args, result TStruct) error { +func (p *TStandardClient) Call(ctx context.Context, method string, args, result TStruct) (ResponseMeta, error) { p.seqId++ seqId := p.seqId if err := p.Send(ctx, p.oprot, seqId, method, args); err != nil { - return err + return ResponseMeta{}, err } // method is oneway if result == nil { - return nil + return ResponseMeta{}, nil } - return p.Recv(ctx, p.iprot, seqId, method, result) + err := p.Recv(ctx, p.iprot, seqId, method, result) + var headers THeaderMap + if hp, ok := p.iprot.(*THeaderProtocol); ok { + headers = hp.transport.readHeaders + } + return ResponseMeta{ + Headers: headers, + }, err } diff --git a/lib/go/thrift/example_client_middleware_test.go b/lib/go/thrift/example_client_middleware_test.go index 8a29083c0..a68cdbc34 100644 --- a/lib/go/thrift/example_client_middleware_test.go +++ b/lib/go/thrift/example_client_middleware_test.go @@ -45,16 +45,16 @@ func NewMyServiceClient(_ TClient) MyService { func simpleClientLoggingMiddleware(next TClient) TClient { return WrappedTClient{ - Wrapped: func(ctx context.Context, method string, args, result TStruct) error { + Wrapped: func(ctx context.Context, method string, args, result TStruct) (ResponseMeta, error) { log.Printf("Before: %q", method) log.Printf("Args: %#v", args) - err := next.Call(ctx, method, args, result) + headers, err := next.Call(ctx, method, args, result) log.Printf("After: %q", method) log.Printf("Result: %#v", result) if err != nil { log.Printf("Error: %v", err) } - return err + return headers, err }, } } diff --git a/lib/go/thrift/header_protocol.go b/lib/go/thrift/header_protocol.go index 35e045805..878041f8d 100644 --- a/lib/go/thrift/header_protocol.go +++ b/lib/go/thrift/header_protocol.go @@ -345,20 +345,6 @@ func (p *THeaderProtocol) SetTConfiguration(cfg *TConfiguration) { p.cfg = cfg } -// GetResponseHeadersFromClient is a helper function to get the read THeaderMap -// from the last response received from the given client. -// -// If the last response was not sent over THeader protocol, -// a nil map will be returned. -func GetResponseHeadersFromClient(c TClient) THeaderMap { - if sc, ok := c.(*TStandardClient); ok { - if hp, ok := sc.iprot.(*THeaderProtocol); ok { - return hp.transport.readHeaders - } - } - return nil -} - var ( _ TConfigurationSetter = (*tHeaderProtocolFactory)(nil) _ TConfigurationSetter = (*THeaderProtocol)(nil) diff --git a/lib/go/thrift/middleware.go b/lib/go/thrift/middleware.go index b575e16c4..8a788df02 100644 --- a/lib/go/thrift/middleware.go +++ b/lib/go/thrift/middleware.go @@ -78,11 +78,11 @@ type ClientMiddleware func(TClient) TClient // // This is provided to aid in developing ClientMiddleware. type WrappedTClient struct { - Wrapped func(ctx context.Context, method string, args, result TStruct) error + Wrapped func(ctx context.Context, method string, args, result TStruct) (ResponseMeta, error) } // Call implements the TClient interface by calling and returning c.Wrapped. -func (c WrappedTClient) Call(ctx context.Context, method string, args, result TStruct) error { +func (c WrappedTClient) Call(ctx context.Context, method string, args, result TStruct) (ResponseMeta, error) { return c.Wrapped(ctx, method, args, result) } diff --git a/lib/go/thrift/middleware_test.go b/lib/go/thrift/middleware_test.go index 2a4d1f957..6c4058fe1 100644 --- a/lib/go/thrift/middleware_test.go +++ b/lib/go/thrift/middleware_test.go @@ -54,7 +54,7 @@ func testProcessorMiddleware(c *counter) ProcessorMiddleware { func testClientMiddleware(c *counter) ClientMiddleware { return func(next TClient) TClient { return WrappedTClient{ - Wrapped: func(ctx context.Context, method string, args, result TStruct) error { + Wrapped: func(ctx context.Context, method string, args, result TStruct) (ResponseMeta, error) { c.incr() return next.Call(ctx, method, args, result) }, @@ -122,8 +122,8 @@ func TestWrapTMultiplexedProcessor(t *testing.T) { func TestWrapClient(t *testing.T) { client := WrappedTClient{ - Wrapped: func(ctx context.Context, method string, args, result TStruct) error { - return nil + Wrapped: func(ctx context.Context, method string, args, result TStruct) (ResponseMeta, error) { + return ResponseMeta{}, nil }, } c := newCounter(t) |