123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109 |
- package thrift
- import (
- "context"
- "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) (ResponseMeta, error)
- }
- type TStandardClient struct {
- seqId int32
- iprot, oprot TProtocol
- }
- // TStandardClient implements TClient, and uses the standard message format for Thrift.
- // It is not safe for concurrent use.
- func NewTStandardClient(inputProtocol, outputProtocol TProtocol) *TStandardClient {
- return &TStandardClient{
- iprot: inputProtocol,
- oprot: outputProtocol,
- }
- }
- func (p *TStandardClient) Send(ctx context.Context, oprot TProtocol, seqId int32, method string, args TStruct) error {
- // Set headers from context object on THeaderProtocol
- if headerProt, ok := oprot.(*THeaderProtocol); ok {
- headerProt.ClearWriteHeaders()
- for _, key := range GetWriteHeaderList(ctx) {
- if value, ok := GetHeader(ctx, key); ok {
- headerProt.SetWriteHeader(key, value)
- }
- }
- }
- if err := oprot.WriteMessageBegin(ctx, method, CALL, seqId); err != nil {
- return err
- }
- if err := args.Write(ctx, oprot); err != nil {
- return err
- }
- if err := oprot.WriteMessageEnd(ctx); err != nil {
- return err
- }
- return oprot.Flush(ctx)
- }
- func (p *TStandardClient) Recv(ctx context.Context, iprot TProtocol, seqId int32, method string, result TStruct) error {
- rMethod, rTypeId, rSeqId, err := iprot.ReadMessageBegin(ctx)
- if err != nil {
- return err
- }
- if method != rMethod {
- return NewTApplicationException(WRONG_METHOD_NAME, fmt.Sprintf("%s: wrong method name", method))
- } else if seqId != rSeqId {
- return NewTApplicationException(BAD_SEQUENCE_ID, fmt.Sprintf("%s: out of order sequence response", method))
- } else if rTypeId == EXCEPTION {
- var exception tApplicationException
- if err := exception.Read(ctx, iprot); err != nil {
- return err
- }
- if err := iprot.ReadMessageEnd(ctx); err != nil {
- return err
- }
- return &exception
- } else if rTypeId != REPLY {
- return NewTApplicationException(INVALID_MESSAGE_TYPE_EXCEPTION, fmt.Sprintf("%s: invalid message type", method))
- }
- if err := result.Read(ctx, iprot); err != nil {
- return err
- }
- return iprot.ReadMessageEnd(ctx)
- }
- 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 ResponseMeta{}, err
- }
- // method is oneway
- if result == nil {
- return ResponseMeta{}, nil
- }
- 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
- }
|