package pool import ( "context" "sync" ) type StickyConnPool struct { pool *ConnPool reusable bool cn *Conn closed bool mu sync.Mutex } var _ Pooler = (*StickyConnPool)(nil) func NewStickyConnPool(pool *ConnPool, reusable bool) *StickyConnPool { return &StickyConnPool{ pool: pool, reusable: reusable, } } func (p *StickyConnPool) NewConn(context.Context) (*Conn, error) { panic("not implemented") } func (p *StickyConnPool) CloseConn(*Conn) error { panic("not implemented") } func (p *StickyConnPool) Get(ctx context.Context) (*Conn, error) { p.mu.Lock() defer p.mu.Unlock() if p.closed { return nil, ErrClosed } if p.cn != nil { return p.cn, nil } cn, err := p.pool.Get(ctx) if err != nil { return nil, err } p.cn = cn return cn, nil } func (p *StickyConnPool) putUpstream() { p.pool.Put(p.cn) p.cn = nil } func (p *StickyConnPool) Put(cn *Conn) {} func (p *StickyConnPool) removeUpstream(reason error) { p.pool.Remove(p.cn, reason) p.cn = nil } func (p *StickyConnPool) Remove(cn *Conn, reason error) { p.removeUpstream(reason) } func (p *StickyConnPool) Len() int { p.mu.Lock() defer p.mu.Unlock() if p.cn == nil { return 0 } return 1 } func (p *StickyConnPool) IdleLen() int { p.mu.Lock() defer p.mu.Unlock() if p.cn == nil { return 1 } return 0 } func (p *StickyConnPool) Stats() *Stats { return nil } func (p *StickyConnPool) Close() error { p.mu.Lock() defer p.mu.Unlock() if p.closed { return ErrClosed } p.closed = true if p.cn != nil { if p.reusable { p.putUpstream() } else { p.removeUpstream(ErrClosed) } } return nil }