| 551 | } |
| 552 | |
| 553 | func (c *Conn) ResetSession(ctx context.Context) error { |
| 554 | if c.conn.IsClosed() { |
| 555 | return driver.ErrBadConn |
| 556 | } |
| 557 | |
| 558 | // Discard connection if it has an open transaction. This can happen if the |
| 559 | // application did not properly commit or rollback a transaction. |
| 560 | if c.conn.PgConn().TxStatus() != 'I' { |
| 561 | return driver.ErrBadConn |
| 562 | } |
| 563 | |
| 564 | now := time.Now() |
| 565 | idle := now.Sub(c.lastResetSessionTime) |
| 566 | |
| 567 | doPing := idle > time.Second // default behavior: ping only if idle > 1s |
| 568 | |
| 569 | if c.shouldPing != nil { |
| 570 | doPing = c.shouldPing(ctx, ShouldPingParams{ |
| 571 | Conn: c.conn, |
| 572 | IdleDuration: idle, |
| 573 | }) |
| 574 | } |
| 575 | |
| 576 | if doPing { |
| 577 | if err := c.conn.PgConn().Ping(ctx); err != nil { |
| 578 | return driver.ErrBadConn |
| 579 | } |
| 580 | } |
| 581 | |
| 582 | c.lastResetSessionTime = now |
| 583 | |
| 584 | return c.resetSessionFunc(ctx, c.conn) |
| 585 | } |
| 586 | |
| 587 | type Stmt struct { |
| 588 | sd *pgconn.StatementDescription |