go.uber.org/yarpc@v1.72.1/encoding/thrift/options.go (about)

     1  // Copyright (c) 2022 Uber Technologies, Inc.
     2  //
     3  // Permission is hereby granted, free of charge, to any person obtaining a copy
     4  // of this software and associated documentation files (the "Software"), to deal
     5  // in the Software without restriction, including without limitation the rights
     6  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     7  // copies of the Software, and to permit persons to whom the Software is
     8  // furnished to do so, subject to the following conditions:
     9  //
    10  // The above copyright notice and this permission notice shall be included in
    11  // all copies or substantial portions of the Software.
    12  //
    13  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    14  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    15  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    16  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    17  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    18  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    19  // THE SOFTWARE.
    20  
    21  package thrift
    22  
    23  import "go.uber.org/thriftrw/protocol"
    24  
    25  type clientConfig struct {
    26  	ServiceName string
    27  	Protocol    protocol.Protocol
    28  	Enveloping  bool
    29  	Multiplexed bool
    30  	NoWire      bool
    31  }
    32  
    33  // ClientOption customizes the behavior of a Thrift client.
    34  type ClientOption interface {
    35  	applyClientOption(*clientConfig)
    36  }
    37  
    38  type registerConfig struct {
    39  	ServiceName string
    40  	Protocol    protocol.Protocol
    41  	Enveloping  bool
    42  	NoWire      bool
    43  }
    44  
    45  // RegisterOption customizes the behavior of a Thrift handler during
    46  // registration.
    47  type RegisterOption interface {
    48  	applyRegisterOption(*registerConfig)
    49  }
    50  
    51  // Option unifies options that apply to both, Thrift clients and handlers.
    52  type Option interface {
    53  	ClientOption
    54  	RegisterOption
    55  }
    56  
    57  // Enveloped is an option that specifies that Thrift requests and responses
    58  // should be enveloped. It defaults to false.
    59  //
    60  // It may be specified on the client side when the client is constructed.
    61  //
    62  // 	client := myserviceclient.New(clientConfig, thrift.Enveloped)
    63  //
    64  // It may be specified on the server side when the handler is registered.
    65  //
    66  // 	dispatcher.Register(myserviceserver.New(handler, thrift.Enveloped))
    67  //
    68  // Note that you will need to enable enveloping to communicate with Apache
    69  // Thrift HTTP servers.
    70  var Enveloped Option = envelopedOption{}
    71  
    72  type envelopedOption struct{}
    73  
    74  func (e envelopedOption) applyClientOption(c *clientConfig) {
    75  	c.Enveloping = true
    76  }
    77  
    78  func (e envelopedOption) applyRegisterOption(c *registerConfig) {
    79  	c.Enveloping = true
    80  }
    81  
    82  // Multiplexed is an option that specifies that requests from a client should
    83  // use Thrift multiplexing. This option should be used if the remote server is
    84  // using Thrift's TMultiplexedProtocol. It includes the name of the service in
    85  // the envelope name for all outbound requests.
    86  //
    87  // Specify this option when constructing the Thrift client.
    88  //
    89  // 	client := myserviceclient.New(clientConfig, thrift.Multiplexed)
    90  //
    91  // This option has no effect if enveloping is disabled.
    92  var Multiplexed ClientOption = multiplexedOption{}
    93  
    94  type multiplexedOption struct{}
    95  
    96  func (multiplexedOption) applyClientOption(c *clientConfig) {
    97  	c.Multiplexed = true
    98  }
    99  
   100  type namedOption struct{ ServiceName string }
   101  
   102  func (n namedOption) applyClientOption(c *clientConfig) {
   103  	if c.ServiceName == "" {
   104  		c.ServiceName = n.ServiceName
   105  	}
   106  }
   107  
   108  func (n namedOption) applyRegisterOption(c *registerConfig) {
   109  	if c.ServiceName == "" {
   110  		c.ServiceName = n.ServiceName
   111  	}
   112  }
   113  
   114  // Named is an option that specifies the name of a thrift.Client.
   115  // This option should be used if a thrift service extends another
   116  // thrift service. Note that the first Named Option will trump all
   117  // other Named options. This ensures that the inherited procedures
   118  // are appropriately labelled with the correct inheriting service's
   119  // name.
   120  //
   121  // Specify this option when constructing the Thrift client.
   122  //
   123  //  client := myserviceclient.New(clientConfig, thrift.Named("foo"))
   124  //
   125  // It may be specified on the server side when the handler is registered.
   126  //
   127  // 	dispatcher.Register(myserviceserver.New(handler, thrift.Named("foo")))
   128  //
   129  // If not specified, the client or server's inherited procedures will
   130  // be labelled with the service name from which they are inherited.
   131  func Named(n string) Option {
   132  	return namedOption{ServiceName: n}
   133  }
   134  
   135  type protocolOption struct{ Protocol protocol.Protocol }
   136  
   137  func (p protocolOption) applyClientOption(c *clientConfig) {
   138  	c.Protocol = p.Protocol
   139  }
   140  
   141  func (p protocolOption) applyRegisterOption(c *registerConfig) {
   142  	c.Protocol = p.Protocol
   143  }
   144  
   145  // Protocol is an option that specifies which Thrift Protocol servers and
   146  // clients should use. It may be specified on the client side when the client
   147  // is constructed,
   148  //
   149  // 	client := myserviceclient.New(clientConfig, thrift.Protocol(protocol.Binary))
   150  //
   151  // It may be specified on the server side when the handler is registered.
   152  //
   153  // 	dispatcher.Register(myserviceserver.New(handler, thrift.Protocol(protocol.Binary)))
   154  //
   155  // It defaults to the Binary protocol.
   156  func Protocol(p protocol.Protocol) Option {
   157  	return protocolOption{Protocol: p}
   158  }
   159  
   160  // NoWire is an option that specifies to *not* use the thriftrw.Wire
   161  // intermediary format. Note that if this is enabled, and a
   162  // 'protocol.Protocol' is provided (e.g., via thrift.Protocol) that provided
   163  // protocol must be able to satisfy the 'stream.RequestReader' interface.
   164  // Will become the default option.
   165  func NoWire(enable bool) Option {
   166  	return noWireOption{Enable: enable}
   167  }
   168  
   169  type noWireOption struct{ Enable bool }
   170  
   171  func (nw noWireOption) applyClientOption(c *clientConfig) {
   172  	c.NoWire = nw.Enable
   173  }
   174  
   175  func (nw noWireOption) applyRegisterOption(c *registerConfig) {
   176  	c.NoWire = nw.Enable
   177  }