diff --git a/pool/tree/pool.go b/pool/tree/pool.go index b77d63a..ab6e98a 100644 --- a/pool/tree/pool.go +++ b/pool/tree/pool.go @@ -1032,6 +1032,16 @@ func (p *Pool) getNewTreeClient(ctx context.Context, node netmap.NodeInfo) (*tre newTreeCl := newTreeClient(addr.URIAddr(), p.dialOptions, p.nodeDialTimeout, p.streamTimeout) if err = newTreeCl.dial(ctx); err != nil { p.log(zap.WarnLevel, "failed to dial tree client", zap.String("address", addr.URIAddr()), zap.Error(err)) + + // We have to close connection here after failed `dial()`. + // This is NOT necessary in object pool and regular tree pool without netmap support, because: + // - object pool uses SDK object client which closes connection during `dial()` call by itself, + // - regular tree pool is going to reuse connection by calling `redialIfNecessary()`. + // Tree pool with netmap support does not operate with background goroutine, so we have to close connection immediately. + if err = newTreeCl.close(); err != nil { + p.log(zap.WarnLevel, "failed to close recently dialed tree client", zap.String("address", addr.URIAddr()), zap.Error(err)) + } + return false }