diff --git a/CHANGELOG.md b/CHANGELOG.md index 5fc8cb2f8..eaa3162e1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,5 @@ +* Fixed deadlock in `Endpoint.String()` method + ## v3.118.3 * Fixed `context` checking in `ydb.Open` diff --git a/internal/endpoint/endpoint.go b/internal/endpoint/endpoint.go index b51f0578e..2f209d344 100644 --- a/internal/endpoint/endpoint.go +++ b/internal/endpoint/endpoint.go @@ -87,7 +87,7 @@ func (e *endpoint) String() string { return fmt.Sprintf(`{id:%d,address:%q,local:%t,location:%q,loadFactor:%f,lastUpdated:%q}`, e.id, - e.Address(), + e.getAddress(), // Use getAddress() to avoid deadlock from nested RLock in Address() e.local, e.location, e.loadFactor, @@ -125,6 +125,12 @@ func (e *endpoint) Address() (address string) { e.mu.RLock() defer e.mu.RUnlock() + return e.getAddress() +} + +// getAddress returns the address without acquiring a lock. +// Caller must ensure the lock is held. +func (e *endpoint) getAddress() string { if len(e.ipv4) != 0 { return getResolvedAddr(e, false) }