Acquire returns a connection ([Conn]) from the [Pool].
(ctx context.Context)
| 596 | |
| 597 | // Acquire returns a connection ([Conn]) from the [Pool]. |
| 598 | func (p *Pool) Acquire(ctx context.Context) (c *Conn, err error) { |
| 599 | if p.acquireTracer != nil { |
| 600 | ctx = p.acquireTracer.TraceAcquireStart(ctx, p, TraceAcquireStartData{}) |
| 601 | defer func() { |
| 602 | var conn *pgx.Conn |
| 603 | if c != nil { |
| 604 | conn = c.Conn() |
| 605 | } |
| 606 | p.acquireTracer.TraceAcquireEnd(ctx, p, TraceAcquireEndData{Conn: conn, Err: err}) |
| 607 | }() |
| 608 | } |
| 609 | |
| 610 | // Try to acquire from the connection pool up to maxConns + 1 times, so that |
| 611 | // any that fatal errors would empty the pool and still at least try 1 fresh |
| 612 | // connection. |
| 613 | for range int(p.maxConns) + 1 { |
| 614 | res, err := p.p.Acquire(ctx) |
| 615 | if err != nil { |
| 616 | return nil, err |
| 617 | } |
| 618 | |
| 619 | cr := res.Value() |
| 620 | |
| 621 | // Destroy expired connections before doing any further work (such as |
| 622 | // pinging) on them. This enforces MaxConnLifetime at acquire time so that |
| 623 | // a connection that expired while idle on a busy pool is not handed out. |
| 624 | if p.isExpired(res) { |
| 625 | p.lifetimeDestroyCount.Add(1) |
| 626 | res.Destroy() |
| 627 | continue |
| 628 | } |
| 629 | |
| 630 | shouldPingParams := ShouldPingParams{Conn: cr.conn, IdleDuration: res.IdleDuration()} |
| 631 | if p.shouldPing(ctx, shouldPingParams) { |
| 632 | err := func() error { |
| 633 | pingCtx := ctx |
| 634 | if p.pingTimeout > 0 { |
| 635 | var cancel context.CancelFunc |
| 636 | pingCtx, cancel = context.WithTimeout(ctx, p.pingTimeout) |
| 637 | defer cancel() |
| 638 | } |
| 639 | return cr.conn.Ping(pingCtx) |
| 640 | }() |
| 641 | if err != nil { |
| 642 | res.Destroy() |
| 643 | continue |
| 644 | } |
| 645 | } |
| 646 | |
| 647 | if p.prepareConn != nil { |
| 648 | ok, err := p.prepareConn(ctx, cr.conn) |
| 649 | if !ok { |
| 650 | res.Destroy() |
| 651 | } |
| 652 | if err != nil { |
| 653 | if ok { |
| 654 | res.Release() |
| 655 | } |