Repository: grpc/grpc-go
File: balancer/randomsubsetting/randomsubsetting.go (Go)

Code before:

func prefixLogger(p *subsettingBalancer) *internalgrpclog.PrefixLogger {
	return internalgrpclog.NewPrefixLogger(logger, fmt.Sprintf("[random-subsetting-lb %p] ", p))
}

func init() {
	balancer.Register(bb{})
}

type bb struct{}

func (bb) Build(cc balancer.ClientConn, bOpts balancer.BuildOptions) balancer.Balancer {
	b := &subsettingBalancer{
		cc:    cc,
		hashf: xxhash.NewWithSeed(uint64(time.Now().UnixNano())),
	}
	// Create a logger with a prefix specific to this balancer instance.
	b.logger = prefixLogger(b)

	b.logger.Infof("Created")
	b.child = gracefulswitch.NewBalancer(cc, bOpts)
	return b
}

// LBConfig is the config for the outlier detection balancer.
type LBConfig struct {
	serviceconfig.LoadBalancingConfig `json:"-"`

	SubsetSize uint64 `json:"subset_size,omitempty"`

	ChildPolicy *iserviceconfig.BalancerConfig `json:"child_policy,omitempty"`
}

func (bb) ParseConfig(s json.RawMessage) (serviceconfig.LoadBalancingConfig, error) {
	lbCfg := &LBConfig{
		// Default top layer values.
		SubsetSize: 10,
	}

	if err := json.Unmarshal(s, lbCfg); err != nil { // Validates child config if present as well.
		return nil, fmt.Errorf("subsetting: unable to unmarshal LBconfig: %s, error: %v", string(s), err)
	}

	// if someonw needs subsetSize == 1, he should use pick_first instead
	if lbCfg.SubsetSize < 2 {
		return nil, errors.New("subsetting: subsetSize must be >= 2")
	}

	return lbCfg, nil
}


Review comment (suggestion):
Is there a reason for this type to be exported. I don't see a reason here. So, if there is no reason, please unexport it. The fields can remain exported since you might want that for JSON marshal/unmarshal.

Code after:

var (
	logger     = grpclog.Component(Name)
	randUint64 = rand.Uint64
)

func prefixLogger(p *subsettingBalancer) *internalgrpclog.PrefixLogger {
	return internalgrpclog.NewPrefixLogger(logger, fmt.Sprintf("[random-subsetting-lb %p] ", p))
}

func init() {
	balancer.Register(bb{})
}

type bb struct{}

func (bb) Build(cc balancer.ClientConn, bOpts balancer.BuildOptions) balancer.Balancer {
	b := &subsettingBalancer{
		Balancer:   gracefulswitch.NewBalancer(cc, bOpts),
		hashSeed:   randUint64(),
		hashDigest: xxhash.New(),
	}
	b.logger = prefixLogger(b)
	b.logger.Infof("Created")
	return b
}

type lbConfig struct {
	serviceconfig.LoadBalancingConfig `json:"-"`

	SubsetSize  uint32                         `json:"subsetSize,omitempty"`
	ChildPolicy *iserviceconfig.BalancerConfig `json:"childPolicy,omitempty"`
}

func (bb) ParseConfig(s json.RawMessage) (serviceconfig.LoadBalancingConfig, error) {
	lbCfg := &lbConfig{}

	// Ensure that the specified child policy is registered and validates its
	// config, if present.
	if err := json.Unmarshal(s, lbCfg); err != nil {
		return nil, fmt.Errorf("randomsubsetting: json.Unmarshal failed for configuration: %s with error: %v", string(s), err)
	}
	if lbCfg.SubsetSize == 0 {
		return nil, fmt.Errorf("randomsubsetting: SubsetSize must be greater than 0")
	}
	if lbCfg.ChildPolicy == nil {
		return nil, fmt.Errorf("randomsubsetting: ChildPolicy must be specified")
	}

	return lbCfg, nil
}