diff --git a/.changelog/5476.bugfix.md b/.changelog/5476.bugfix.md new file mode 100644 index 00000000000..4e6aea1eb94 --- /dev/null +++ b/.changelog/5476.bugfix.md @@ -0,0 +1 @@ +go/p2p/discovery: Close only idle connections to seed node diff --git a/go/p2p/discovery/bootstrap/client.go b/go/p2p/discovery/bootstrap/client.go index 61d31c6449a..6e8f3c1424e 100644 --- a/go/p2p/discovery/bootstrap/client.go +++ b/go/p2p/discovery/bootstrap/client.go @@ -133,9 +133,9 @@ func (c *client) Advertise(ctx context.Context, ns string, _ ...discovery.Option pf.RecordSuccess() - // Close connections after every call because requests to the seed node are infrequent. - if err = c.rc.Close(c.seed.ID); err != nil { - c.logger.Warn("failed to close connections to seed node", + // Try to close connections after every call because requests to the seed node are infrequent. + if err = c.rc.CloseIdle(c.seed.ID); err != nil { + c.logger.Warn("failed to close idle connections to seed node", "err", err, ) } @@ -246,9 +246,9 @@ func (c *client) fetchPeers(ctx context.Context, ns string, limit int) []peer.Ad pf.RecordFailure() } - // Close connections after every call because requests to the seed node are infrequent. - if err := c.rc.Close(c.seed.ID); err != nil { - c.logger.Warn("failed to close connections to seed node", + // Try to close connections after every call because requests to the seed node are infrequent. + if err = c.rc.CloseIdle(c.seed.ID); err != nil { + c.logger.Warn("failed to close idle connections to seed node", "err", err, ) } diff --git a/go/p2p/rpc/client.go b/go/p2p/rpc/client.go index 195a0fbeaa1..f9af4cd0c94 100644 --- a/go/p2p/rpc/client.go +++ b/go/p2p/rpc/client.go @@ -256,6 +256,9 @@ type Client interface { // Close closes all connections to the given peer. Close(peerID core.PeerID) error + // CloseIdle closes all connections to the given peer that have no open streams. + CloseIdle(peerID core.PeerID) error + // RegisterListener subscribes the listener to the client notification events. // If the listener is already registered this is a noop operation. RegisterListener(l ClientListener) @@ -545,6 +548,19 @@ func (c *client) Close(peerID core.PeerID) error { return errs } +// Implements Client. +func (c *client) CloseIdle(peerID core.PeerID) error { + var errs error + for _, conn := range c.host.Network().ConnsToPeer(peerID) { + if len(conn.GetStreams()) > 0 { + continue + } + err := conn.Close() + errs = errors.Join(errs, err) + } + return errs +} + // Implements Client. func (c *client) RegisterListener(l ClientListener) { c.listeners.Lock() diff --git a/go/p2p/rpc/nop.go b/go/p2p/rpc/nop.go index d38842a83f9..68212434aa1 100644 --- a/go/p2p/rpc/nop.go +++ b/go/p2p/rpc/nop.go @@ -89,6 +89,13 @@ func (c *nopClient) Close( return nil } +// Implements Client. +func (c *nopClient) CloseIdle( + peer.ID, +) error { + return nil +} + // Implements Client. func (c *nopClient) RegisterListener(ClientListener) {}