Skip to content

Add PrepareConn hook, which extends BeforeAcquire's behavior to allow… #2329

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 31, 2025

Conversation

flimzy
Copy link
Contributor

@flimzy flimzy commented May 21, 2025

… canceling the instigating query

  • BeforeAcquire now marked as deprecated, and re-implemented in terms of PrepareConn
  • PrepareConn now takes precidence over BeforeAcquire if both are provided
  • New tests added, so both old and new behavior are tested
  • One niggle: AcquireAllIdle does not return an error, so the only recourse that seems reasonable when PrepareConn returns an error in that context, is to destroy the connection. This more or less retains the spirit of existing functionality, without changing the public API of that method. Although maybe an error-returning variant would be a useful addition as well.

Fixes: #2328

… canceling the instigating query

- BeforeAcquire now marked as deprecated, and re-implemented in terms of PrepareConn
- PrepareConn now takes precidence over BeforeAcquire if both are provided
- New tests added, so both old and new behavior are tested
- One niggle: AcquireAllIdle does not return an error, so the only recourse
  that seems reasonable when PrepareConn returns an error in that context,
  is to destroy the connection.  This more or less retains the spirit of
  existing functionality, without changing the public API of that method.
  Although maybe an error-returning variant would be a useful addition as
  well.
Copy link
Owner

@jackc jackc left a comment

Choose a reason for hiding this comment

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

After looking at the comments describing the return values for PrepareConn, I'm now questioning its interface. It definitely needs to be read a few times to understand. It's tricky because we are using it to signal multiple things on failure.

  • Should the connection be destroyed?
  • Should the PrepareConn be retried on a new connection?
  • What error should be returned to the caller?

I'm thinking that whether an error is returned should be the sole determinant of whether PrepareConn succeeded or not and if Acquire ultimately fails that should be the error returned to the caller.

But that still leaves "should destroy" and "should retry".

I wonder if the following signature would be clearer:

func(context.Context, *pgx.Conn) (retry bool, destroyConn, err error)

Or maybe we should create a specific PrepareConnError type or interface that has those fields or methods. That could allow for further extensibility. I don't see what extensibility would be needed, but obviously I didn't foresee the insufficiency of BeforeAcquire either.

Or maybe fixing / improving the comments further would be sufficient. 🤷

// - It must return true and a nil error to allow acquisition and the query to proceed.
// - If it returns true and an error, the connection will be returned to the pool, and the instigating query will fail with the returned error.
// - If it returns false, and an error, the query will fail with the returned error, and the connection will be destroyed.
// - If it returns false and a nil error, the connection will be returned to the pool, and the instigating query will be retried on a new connection.
Copy link
Owner

Choose a reason for hiding this comment

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

Is this comment correct? I thought (false, nil) should destroy the connection.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You are correct. The comment is wrong.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've updated the GoDoc, and made it a bit more symmetrical for ease of understanding. Give it a look and see if it's now clear enough, or if a different API is still a better idea.

Copy link
Owner

Choose a reason for hiding this comment

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

The new docs are much clearer. I think that will work. Merged!

@jackc jackc merged commit 4015a0c into jackc:master May 31, 2025
14 checks passed
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.

BeforeAcquire: Allow aborting the query
2 participants