geektutu/7days-golang · error
RegisterPeerPicker called more than once
Error message
RegisterPeerPicker called more than once
What it means
Group.RegisterPeers panics if called more than once on the same Group. The peers (PeerPicker) is designed to be set exactly once at startup; re-registering would silently replace the peer selection strategy and break in-flight loads. This is a misuse guard against double initialization.
Source
Thrown at gee-cache/day7-proto-buf/geecache/geecache.go:83
// 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) {
// each key is only fetched once (either locally or remotely)
// regardless of the number of concurrent callers.
viewi, err := g.loader.Do(key, func() (interface{}, 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)View on GitHub (pinned to cf36443821)
Solutions
- Call RegisterPeers exactly once per Group, at initialization time
- If peer configuration changed, create a new Group instead of re-registering
- Guard the call site with an 'if g.Peers() == nil' style check or a sync.Once
- Restructure tests so each Group is used by only one RegisterPeers call
Example fix
// before
g.RegisterPeers(peers)
// ... later ...
g.RegisterPeers(newPeers) // panics
// after
if g.Peers() == nil {
g.RegisterPeers(newPeers)
} else {
g = geecache.NewGroup("scores", 2<<20, getter)
g.RegisterPeers(newPeers)
} Defensive patterns
Strategy: validation
Validate before calling
if g.Peers() == nil {
g.RegisterPeers(peers)
} Try / catch
// Go panics cannot be caught by try/catch; guard at call site or recover:
func safeRegister(g *geecache.Group, peers geecache.PeerPicker) (ok bool) {
defer func() { if recover() != nil { ok = false } }()
g.RegisterPeers(peers)
return true
} Prevention
- Register peers once during process startup, never per-request
- Use sync.Once around RegisterPeers
- In tests, create a fresh Group per test instead of reusing
When it happens
Trigger: Calling g.RegisterPeers(peers) a second time on a Group that already has peers registered, typically during re-configuration, hot-reload, or calling RegisterPeers in both setup code and a test helper.
Common situations: Test setups that build servers twice in one process; restarting the peer server without recreating the Group; accidentally calling RegisterPeers inside a loop or per-request path.
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/a49af665bd16bcad.
Report an issue: GitHub.