Skip to content

Conversation

StephenCathcart
Copy link
Contributor

When multiple goroutines access the pool concurrently, one may remove all servers from the routing table while another is trying to borrow a connection, resulting in a PoolOutOfServers error. This error should trigger a retry with a fresh routing table fetch, similar to PoolTimeout.

  • Add PoolOutOfServers to retryable errors in IsRetryable().
  • Wrap PoolOutOfServers as ConnectivityError for consistency.

When multiple goroutines access the pool concurrently, one may remove
all servers from the routing table while another is trying to borrow
a connection, resulting in a PoolOutOfServers error. This error should
trigger a retry with a fresh routing table fetch, similar to PoolTimeout.

- Add PoolOutOfServers to retryable errors in IsRetryable().
- Wrap PoolOutOfServers as ConnectivityError for consistency.
Comment on lines +144 to +146
if _, ok := err.(*errorutil.PoolOutOfServers); ok {
return true
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If my search-foo didn't let me down, I don't think that IsRetryable is ever being called on an unwrapped error. Therefore, I doubt this code-path ever gets hit.

If, however, we want IsRetryable to also work for unwrapped errors, there'd be more to do here. Many errors get wrapped in ConnectivityError which makes them retryable. So all of those would probably also need a special check here.

Not a blocker though, as I doubt it'll break anything. Except for devs after us wondering why this if was put here with some intention 🙃

Copy link
Contributor Author

@StephenCathcart StephenCathcart Oct 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, good catch, in my head, IsRetryable is a public API, therefore I thought we needed a case for the error for users with custom retry logic, but the internal retry flow in Continue()
wraps errors before checking (IsRetryable(errorutil.WrapError(lastErr))), so the direct check never gets hit there.

Happy to remove this, especially if there needs to be more work anyway to make other unwrapped errors work correctly - what's your thoughts?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

therefore I thought we needed a case for the error for users with custom retry logic

Will such user-written retry loop see the wrapped or unwarpped error? If it ever sees the unwrapped/raw error (PoolOutOfServers), then I totally agree, that this check should remain (and other errors might also need to be added here).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants