geektutu/7days-golang · error

rpc discovery: not supported select mode

Error message

rpc discovery: not supported select mode

What it means

Guard in MultiServersDiscovery.Get: the SelectMode passed is neither RandomSelect nor RoundRobinSelect, so no load-balancing strategy applies. It fires when a caller uses an unimplemented or invalid select mode constant.

Source

Thrown at gee-rpc/day6-load-balance/xclient/discovery.go:65

}

// Get a server according to mode
func (d *MultiServersDiscovery) Get(mode SelectMode) (string, error) {
	d.mu.Lock()
	defer d.mu.Unlock()
	n := len(d.servers)
	if n == 0 {
		return "", errors.New("rpc discovery: no available servers")
	}
	switch mode {
	case RandomSelect:
		return d.servers[d.r.Intn(n)], nil
	case RoundRobinSelect:
		s := d.servers[d.index%n] // servers could be updated, so mode n to ensure safety
		d.index = (d.index + 1) % n
		return s, nil
	default:
		return "", errors.New("rpc discovery: not supported select mode")
	}
}

// returns all servers in discovery
func (d *MultiServersDiscovery) GetAll() ([]string, error) {
	d.mu.RLock()
	defer d.mu.RUnlock()
	// return a copy of d.servers
	servers := make([]string, len(d.servers), len(d.servers))
	copy(servers, d.servers)
	return servers, nil
}

// NewMultiServerDiscovery creates a MultiServersDiscovery instance
func NewMultiServerDiscovery(servers []string) *MultiServersDiscovery {
	d := &MultiServersDiscovery{
		servers: servers,
		r:       rand.New(rand.NewSource(time.Now().UnixNano())),

View on GitHub (pinned to cf36443821)

Solutions

  1. Use only the exported constants: xclient.RandomSelect or xclient.RoundRobinSelect.
  2. Validate any externally supplied mode value against the supported constants before calling Get.
  3. If you need a new strategy, add a case to MultiServersDiscovery.Get and define a new SelectMode constant.

Example fix

// before
mode := xclient.SelectMode(cfg.Mode) // arbitrary int
addr, err := d.Get(mode)
// after
var mode xclient.SelectMode = xclient.RoundRobinSelect
if cfg.Mode == "random" { mode = xclient.RandomSelect }
addr, err := d.Get(mode)
Defensive patterns

Strategy: validation

Validate before calling

func validMode(m xclient.SelectMode) bool {
    return m == xclient.RandomSelect || m == xclient.RoundRobinSelect
}

Try / catch

if !validMode(mode) { return errors.New("mode must be RandomSelect or RoundRobinSelect") }
addr, err := d.Get(mode)

Prevention

When it happens

Trigger: Calling Get(mode) with an int SelectMode outside the defined constants (e.g. 2, -1, or a value from a different package's enum), or passing the wrong enum type cast to SelectMode.

Common situations: Config-driven mode selection parsing user input into an unvalidated int, mixing up SelectMode constants from another load-balancer package, or extending the enum locally without adding a case in Get.

Related errors


AI-assisted analysis of geektutu/7days-golang@cf36443821 (2026-09-03). Data as JSON: /api/errors/4268c6a55b2f3ed3. Report an issue: GitHub.