Copyright 2020 Google LLC. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.

package grpc

import (
	
	
	

	
	
)
ConnPool is a pool of grpc.ClientConns.
type ConnPool = internal.ConnPool // NOTE(cbro): type alias to export the type. It must live in internal to avoid a circular dependency.

var _ ConnPool = &roundRobinConnPool{}
var _ ConnPool = &singleConnPool{}
singleConnPool is a special case for a single connection.
type singleConnPool struct {
	*grpc.ClientConn
}

func ( *singleConnPool) () *grpc.ClientConn { return .ClientConn }
func ( *singleConnPool) () int               { return 1 }

type roundRobinConnPool struct {
	conns []*grpc.ClientConn

	idx uint32 // access via sync/atomic
}

func ( *roundRobinConnPool) () int {
	return len(.conns)
}

func ( *roundRobinConnPool) () *grpc.ClientConn {
	 := atomic.AddUint32(&.idx, 1)
	return .conns[%uint32(len(.conns))]
}

func ( *roundRobinConnPool) () error {
	var  multiError
	for ,  := range .conns {
		if  := .Close();  != nil {
			 = append(, )
		}
	}
	if len() == 0 {
		return nil
	}
	return 
}

func ( *roundRobinConnPool) ( context.Context,  string,  interface{},  interface{},  ...grpc.CallOption) error {
	return .Conn().Invoke(, , , , ...)
}

func ( *roundRobinConnPool) ( context.Context,  *grpc.StreamDesc,  string,  ...grpc.CallOption) (grpc.ClientStream, error) {
	return .Conn().NewStream(, , , ...)
}
multiError represents errors from multiple conns in the group. TODO: figure out how and whether this is useful to export. End users should not be depending on the transport/grpc package directly, so there might need to be some service-specific multi-error type.
type multiError []error

func ( multiError) () string {
	,  := "", 0
	for ,  := range  {
		if  != nil {
			if  == 0 {
				 = .Error()
			}
			++
		}
	}
	switch  {
	case 0:
		return "(0 errors)"
	case 1:
		return 
	case 2:
		return  + " (and 1 other error)"
	}
	return fmt.Sprintf("%s (and %d other errors)", , -1)