Skip to content
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

pgxpool: acquire wait time stats #1669

Open
redbaron opened this issue Jul 2, 2023 · 3 comments
Open

pgxpool: acquire wait time stats #1669

redbaron opened this issue Jul 2, 2023 · 3 comments

Comments

@redbaron
Copy link
Contributor

redbaron commented Jul 2, 2023

Is your feature request related to a problem? Please describe.
I'd like to better understand the impact of a fully utilized connection pool. That is the case when there is no idle connections and app tries to acquire one.

There is Stat.EmptyAcquireCount, which is a good start, but it doesn't give full picture. I'd like to be able to get a histogram of times app waited for connection

Describe the solution you'd like
Histogram could be taken if there were OnAcquireStart and OnAcquireComplete, which are called as the very first and very last operation in Pool.Acquire. Alternatively pgxpool could expose histogram in the Stat.

Describe alternatives you've considered
Creting own wrapper around Pool.Acquire func, but this requires changing all call-sites in the app.

Additional context
Add any other context or screenshots about the feature request here.

@jackc
Copy link
Owner

jackc commented Jul 7, 2023

Histogram could be taken if there were OnAcquireStart and OnAcquireComplete, which are called as the very first and very last operation in Pool.Acquire. Alternatively pgxpool could expose histogram in the Stat.

If this is to be done, at least some of the change should be done in the puddle library. Getting the time is cheap, but not free, and it is already done internally in the puddle acquire logic. It might make sense to add a field to puddle.Resource for acquire duration (maybe other fields to like whether a new resource was created, whether it blocked, etc.).

Then the changes in pgxpool would be smaller as well.

@jameshartig
Copy link
Contributor

jameshartig commented Jul 20, 2023

What we do is a bit hacky but essentially:

cfg.BeforeAcquire = func(ctx context.Context, c *pgx.Conn) bool {
  t, ok := ctx.Value(contextKeyAcquired).(*time.Time)
  if ok {
    *t = time.Now()
  }
  return true
}
...
var acquired time.Time
ctx = context.WithValue(ctx, contextKeyAcquired, &acquired)
now := time.Now()
pool.Exec(ctx, ...)
waiting := acquired.Sub(now)

@vamshiaruru
Copy link

vamshiaruru commented Dec 27, 2024

So even with both the above PRs, we would still not be able to get a histogram of how much time it took to acquire the connection, right?

I am not very well versed with pgx code base, but can we leverage acquire tracer to do this?

	if p.acquireTracer != nil {
		ctx = p.acquireTracer.TraceAcquireStart(ctx, p, TraceAcquireStartData{})
		defer func() {
			var conn *pgx.Conn
			if c != nil {
				conn = c.Conn()
			}
			p.acquireTracer.TraceAcquireEnd(ctx, p, TraceAcquireEndData{Conn: conn, Err: err})
		}()
	}

It seems like passing the start time in context in TraceAcquireStart and reading in TraceAcquireEnd and registering in a histogram would work?

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

No branches or pull requests

4 participants