mirror of
https://github.com/wneessen/go-mail.git
synced 2024-11-15 02:12:55 +01:00
Add new error handling and connection management in connpool
Introduce ErrClosed and ErrNilConn errors for better error handling. Implement Close and MarkUnusable methods for improved connection lifecycle management. Add put method to return connections to the pool or close them if necessary.
This commit is contained in:
parent
1394f1fc20
commit
d6e5034bba
1 changed files with 48 additions and 2 deletions
50
connpool.go
50
connpool.go
|
@ -17,11 +17,13 @@ import (
|
|||
// concurrency template.
|
||||
|
||||
var (
|
||||
// ErrClosed is returned when an operation is attempted on a closed connection pool.
|
||||
ErrClosed = errors.New("connection pool is closed")
|
||||
// ErrNilConn is returned when a nil connection is passed back to the connection pool.
|
||||
ErrNilConn = errors.New("connection is nil")
|
||||
// ErrPoolInvalidCap is returned when the connection pool's capacity settings are
|
||||
// invalid (e.g., initial capacity is negative).
|
||||
ErrPoolInvalidCap = errors.New("invalid connection pool capacity settings")
|
||||
// ErrClosed is returned when an operation is attempted on a closed connection pool.
|
||||
ErrClosed = errors.New("connection pool is closed")
|
||||
)
|
||||
|
||||
// Pool interface describes a connection pool implementation. A Pool is
|
||||
|
@ -66,6 +68,28 @@ type PoolConn struct {
|
|||
unusable bool
|
||||
}
|
||||
|
||||
// Close puts a given pool connection back to the pool instead of closing it.
|
||||
func (c *PoolConn) Close() error {
|
||||
c.mutex.RLock()
|
||||
defer c.mutex.RUnlock()
|
||||
|
||||
if c.unusable {
|
||||
if c.Conn != nil {
|
||||
return c.Conn.Close()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return c.pool.put(c.Conn)
|
||||
}
|
||||
|
||||
// MarkUnusable marks the connection not usable any more, to let the pool close it instead
|
||||
// of returning it to pool.
|
||||
func (c *PoolConn) MarkUnusable() {
|
||||
c.mutex.Lock()
|
||||
c.unusable = true
|
||||
c.mutex.Unlock()
|
||||
}
|
||||
|
||||
// NewConnPool returns a new pool based on buffered channels with an initial
|
||||
// capacity and maximum capacity. The DialContextFunc is used when the initial
|
||||
// capacity is greater than zero to fill the pool. A zero initialCap doesn't
|
||||
|
@ -167,6 +191,28 @@ func (p *connPool) getConnsAndDialContext() (context.Context, chan net.Conn, Dia
|
|||
return ctx, conns, dialCtxFunc
|
||||
}
|
||||
|
||||
// put puts a passed connection back into the pool. If the pool is full or closed,
|
||||
// conn is simply closed. A nil conn will be rejected with an error.
|
||||
func (p *connPool) put(conn net.Conn) error {
|
||||
if conn == nil {
|
||||
return ErrNilConn
|
||||
}
|
||||
|
||||
p.mutex.RLock()
|
||||
defer p.mutex.RUnlock()
|
||||
|
||||
if p.conns == nil {
|
||||
return conn.Close()
|
||||
}
|
||||
|
||||
select {
|
||||
case p.conns <- conn:
|
||||
return nil
|
||||
default:
|
||||
return conn.Close()
|
||||
}
|
||||
}
|
||||
|
||||
// wrapConn wraps a given net.Conn with a PoolConn, modifying the net.Conn's Close() method.
|
||||
func (p *connPool) wrapConn(conn net.Conn) net.Conn {
|
||||
poolconn := &PoolConn{pool: p}
|
||||
|
|
Loading…
Reference in a new issue