geektutu/7days-golang · error
RegisterPeerPicker called more than once
Error message
RegisterPeerPicker called more than once
What it means
Group.RegisterPeers panics if it is called twice on the same Group: g.peers is already non-nil. Peer selection (the PeerPicker) is intended to be configured exactly once per group; re-registering would silently replace the peer topology mid-flight, so the library panics to surface the double initialization.
Source
Thrown at gee-cache/day5-multi-nodes/geecache/geecache.go:77
// Get value for a key from cache
func (g *Group) Get(key string) (ByteView, error) {
if key == "" {
return ByteView{}, fmt.Errorf("key is required")
}
if v, ok := g.mainCache.get(key); ok {
log.Println("[GeeCache] hit")
return v, nil
}
return g.load(key)
}
// RegisterPeers registers a PeerPicker for choosing remote peer
func (g *Group) RegisterPeers(peers PeerPicker) {
if g.peers != nil {
panic("RegisterPeerPicker called more than once")
}
g.peers = peers
}
func (g *Group) load(key string) (value ByteView, err error) {
if g.peers != nil {
if peer, ok := g.peers.PickPeer(key); ok {
if value, err = g.getFromPeer(peer, key); err == nil {
return value, nil
}
log.Println("[GeeCache] Failed to get from peer", err)
}
}
return g.getLocally(key)
}
func (g *Group) populateCache(key string, value ByteView) {View on GitHub (pinned to cf36443821)
Solutions
- Call RegisterPeers exactly once per Group, right after NewGroup
- Recreate the Group (or guard registration with a sync.Once / nil check) instead of re-registering
- Refactor startup so peer setup happens in a single code path
Example fix
// before
grp.RegisterPeers(peers)
// on reload:
grp.RegisterPeers(newPeers) // panic: RegisterPeerPicker called more than once
// after
if grp.GetPeers() == nil { // or use sync.Once
grp.RegisterPeers(newPeers)
} Defensive patterns
Strategy: validation
Validate before calling
var peersRegistered sync.Once
func registerPeers(g *geecache.Group, p geecache.PeerPicker) {
peersRegistered.Do(func() { g.RegisterPeers(p) })
} Try / catch
defer func() {
if r := recover(); r == "RegisterPeerPicker called more than once" {
log.Println("peers already registered, ignoring")
}
}()
g.RegisterPeers(peers) Prevention
- Call RegisterPeers exactly once, immediately after NewGroup
- Wrap registration in sync.Once for idempotent startup
- Never re-register peers on config reload — recreate the Group instead
- Keep peer setup in a single startup function
When it happens
Trigger: Calling RegisterPeers twice on one Group — e.g. startCacheServer executed more than once for the same group in tests, re-running registration on config reload, or registering the same pool from two init paths.
Common situations: Test harness reusing a Group across subtests; hot-reload code re-applying peer config without recreating the Group; duplicated initialization in main and a helper.
Related errors
- RegisterPeerPicker called more than once
- RegisterPeerPicker called more than once
- nil Getter
- nil Getter
- nil Getter
AI-assisted analysis of geektutu/7days-golang@cf36443821 (2026-09-03).
Data as JSON: /api/errors/ca2356c7a8e9576a.
Report an issue: GitHub.