(cn *Conn, nowNs int64)
| 1712 | } |
| 1713 | |
| 1714 | func (p *ConnPool) isHealthyConn(cn *Conn, nowNs int64) bool { |
| 1715 | // Performance optimization: check conditions from cheapest to most expensive, |
| 1716 | // and from most likely to fail to least likely to fail. |
| 1717 | |
| 1718 | // Only fails if ConnMaxLifetime is set AND connection is old. |
| 1719 | // Most pools don't set ConnMaxLifetime, so this rarely fails. |
| 1720 | if p.cfg.ConnMaxLifetime > 0 { |
| 1721 | if cn.expiresAt.UnixNano() < nowNs { |
| 1722 | return false // Connection has exceeded max lifetime |
| 1723 | } |
| 1724 | } |
| 1725 | |
| 1726 | // Most pools set ConnMaxIdleTime, and idle connections are common. |
| 1727 | // Checking this first allows us to fail fast without expensive syscalls. |
| 1728 | if p.cfg.ConnMaxIdleTime > 0 { |
| 1729 | if nowNs-cn.UsedAtNs() >= int64(p.cfg.ConnMaxIdleTime) { |
| 1730 | return false // Connection has been idle too long |
| 1731 | } |
| 1732 | } |
| 1733 | |
| 1734 | // Only run this if the cheap checks passed. |
| 1735 | if err := connCheck(cn.getNetConn()); err != nil { |
| 1736 | // If there's unexpected data, it might be push notifications (RESP3) |
| 1737 | if p.cfg.PushNotificationsEnabled && err == errUnexpectedRead { |
| 1738 | // Peek at the reply type to check if it's a push notification |
| 1739 | if replyType, err := cn.rd.PeekReplyType(); err == nil && replyType == proto.RespPush { |
| 1740 | // For RESP3 connections with push notifications, we allow some buffered data |
| 1741 | // The client will process these notifications before using the connection |
| 1742 | internal.Logger.Printf( |
| 1743 | context.Background(), |
| 1744 | "push: conn[%d] has buffered data, likely push notifications - will be processed by client", |
| 1745 | cn.GetID(), |
| 1746 | ) |
| 1747 | |
| 1748 | // Update timestamp for healthy connection |
| 1749 | cn.SetUsedAtNs(nowNs) |
| 1750 | |
| 1751 | // Connection is healthy, client will handle notifications |
| 1752 | return true |
| 1753 | } |
| 1754 | // Not a push notification - treat as unhealthy |
| 1755 | return false |
| 1756 | } |
| 1757 | // Connection failed health check |
| 1758 | return false |
| 1759 | } |
| 1760 | |
| 1761 | // Only update UsedAt if connection is healthy (avoids unnecessary atomic store) |
| 1762 | cn.SetUsedAtNs(nowNs) |
| 1763 | return true |
| 1764 | } |
no test coverage detected