github.com/jtzjtz/kit@v1.0.2/conn/grpc_pool/options.go (about)

     1  package grpc_pool
     2  
     3  import (
     4  	"errors"
     5  	"math/rand"
     6  	"sync"
     7  	"time"
     8  )
     9  
    10  var (
    11  	errClosed       = errors.New("conn is closed")
    12  	errInvalid      = errors.New("invalid config")
    13  	errRejected     = errors.New("connection is nil. rejecting")
    14  	errTargets      = errors.New("targets server is empty")
    15  	errTooManyConns = errors.New("too many conns")
    16  )
    17  
    18  func init() {
    19  	rand.NewSource(time.Now().UnixNano())
    20  }
    21  
    22  //Options conn options
    23  type Options struct {
    24  	lock sync.RWMutex
    25  	//targets node
    26  	targets *[]string
    27  	//targets channel
    28  	input chan *[]string
    29  
    30  	//InitTargets init targets
    31  	InitTargets []string
    32  	// init connection
    33  	InitCap int
    34  	// max connections
    35  	MaxCap      int
    36  	DialTimeout time.Duration
    37  	IdleTimeout time.Duration
    38  }
    39  
    40  // Input is the input channel
    41  func (o *Options) Input() chan<- *[]string {
    42  	return o.input
    43  }
    44  
    45  // update targets
    46  func (o *Options) update() {
    47  	//init targets
    48  	o.targets = &o.InitTargets
    49  
    50  	go func() {
    51  		for targets := range o.input {
    52  			if targets == nil {
    53  				continue
    54  			}
    55  
    56  			o.lock.Lock()
    57  			o.targets = targets
    58  			o.lock.Unlock()
    59  		}
    60  	}()
    61  
    62  }
    63  
    64  // NewOptions returns a new newOptions instance with sane defaults.
    65  func NewOptions() *Options {
    66  	o := &Options{}
    67  	o.InitCap = 5
    68  	o.MaxCap = 100
    69  	o.DialTimeout = 5 * time.Second
    70  	o.IdleTimeout = 60 * time.Second
    71  	return o
    72  }
    73  
    74  // validate checks a Config instance.
    75  func (o *Options) validate() error {
    76  	if o.InitTargets == nil ||
    77  		o.InitCap <= 0 ||
    78  		o.MaxCap <= 0 ||
    79  		o.InitCap > o.MaxCap ||
    80  		o.DialTimeout == 0 {
    81  		return errInvalid
    82  	}
    83  	return nil
    84  }
    85  
    86  //nextTarget next target implement load balance
    87  func (o *Options) nextTarget() string {
    88  	o.lock.RLock()
    89  	defer o.lock.RUnlock()
    90  
    91  	tlen := len(*o.targets)
    92  	if tlen <= 0 {
    93  		return ""
    94  	}
    95  
    96  	//rand server
    97  	return (*o.targets)[rand.Int()%tlen]
    98  }