github.com/uber-go/tally/v4@v4.1.17/m3/thriftudp/multitransport.go (about)

     1  // Copyright (c) 2021 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 thriftudp
    22  
    23  import (
    24  	"fmt"
    25  
    26  	"github.com/uber-go/tally/v4/thirdparty/github.com/apache/thrift/lib/go/thrift"
    27  )
    28  
    29  // TMultiUDPTransport does multiUDP as a thrift.TTransport
    30  type TMultiUDPTransport struct {
    31  	transports []thrift.TTransport
    32  }
    33  
    34  // NewTMultiUDPClientTransport creates a set of net.UDPConn-backed TTransports for Thrift clients
    35  // All writes are buffered and flushed in one UDP packet. If locHostPort is not "", it
    36  // will be used as the local address for the connection
    37  // Example:
    38  // 	trans, err := thriftudp.NewTMultiUDPClientTransport([]string{"192.168.1.1:9090","192.168.1.2:9090"}, "")
    39  func NewTMultiUDPClientTransport(
    40  	destHostPorts []string,
    41  	locHostPort string,
    42  ) (*TMultiUDPTransport, error) {
    43  	var transports []thrift.TTransport
    44  	for i := range destHostPorts {
    45  		trans, err := NewTUDPClientTransport(destHostPorts[i], locHostPort)
    46  		if err != nil {
    47  			return nil, err
    48  		}
    49  		transports = append(transports, trans)
    50  	}
    51  
    52  	return &TMultiUDPTransport{transports: transports}, nil
    53  }
    54  
    55  // Open the connections of the underlying transports
    56  func (p *TMultiUDPTransport) Open() error {
    57  	for _, trans := range p.transports {
    58  		if err := trans.Open(); err != nil {
    59  			return err
    60  		}
    61  	}
    62  	return nil
    63  }
    64  
    65  // IsOpen returns true if the connections of the underlying transports are open
    66  func (p *TMultiUDPTransport) IsOpen() bool {
    67  	for _, trans := range p.transports {
    68  		if open := trans.IsOpen(); !open {
    69  			return false
    70  		}
    71  	}
    72  	return true
    73  }
    74  
    75  // Close closes the connections of the underlying transports
    76  func (p *TMultiUDPTransport) Close() error {
    77  	for _, trans := range p.transports {
    78  		if err := trans.Close(); err != nil {
    79  			return err
    80  		}
    81  	}
    82  	return nil
    83  }
    84  
    85  // Read is not supported for multiple underlying transports
    86  func (p *TMultiUDPTransport) Read(buf []byte) (int, error) {
    87  	// Not applicable, required by TTransport however
    88  	return 0, fmt.Errorf("not supported")
    89  }
    90  
    91  // RemainingBytes is not supported for multiple underlying transports
    92  func (p *TMultiUDPTransport) RemainingBytes() uint64 {
    93  	// Not applicable, required by TTransport however
    94  	return 0
    95  }
    96  
    97  // Write writes specified buf to the write buffer of underlying transports
    98  func (p *TMultiUDPTransport) Write(buff []byte) (int, error) {
    99  	n := 0
   100  	for _, trans := range p.transports {
   101  		written, err := trans.Write(buff)
   102  		if err != nil {
   103  			return n, err
   104  		}
   105  		if written > n {
   106  			n = written
   107  		}
   108  	}
   109  	return n, nil
   110  }
   111  
   112  // Flush flushes the write buffer of the underlying transports
   113  func (p *TMultiUDPTransport) Flush() error {
   114  	for _, trans := range p.transports {
   115  		if err := trans.Flush(); err != nil {
   116  			return err
   117  		}
   118  	}
   119  	return nil
   120  }