committed by
Jack Christensen
parent
88079de700
commit
91c9e841e1
@@ -70,6 +70,16 @@ func (cr *connResource) getPoolRows(c *Conn, r pgx.Rows) *poolRows {
|
|||||||
return pr
|
return pr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// detachedCtx wraps a context and will never be canceled, regardless of if
|
||||||
|
// the wrapped one is cancelled. The Err() method will never return any errors.
|
||||||
|
type detachedCtx struct {
|
||||||
|
context.Context
|
||||||
|
}
|
||||||
|
|
||||||
|
func (detachedCtx) Done() <-chan struct{} { return nil }
|
||||||
|
func (detachedCtx) Deadline() (time.Time, bool) { return time.Time{}, false }
|
||||||
|
func (detachedCtx) Err() error { return nil }
|
||||||
|
|
||||||
// Pool allows for connection reuse.
|
// Pool allows for connection reuse.
|
||||||
type Pool struct {
|
type Pool struct {
|
||||||
p *puddle.Pool
|
p *puddle.Pool
|
||||||
@@ -195,6 +205,14 @@ func ConnectConfig(ctx context.Context, config *Config) (*Pool, error) {
|
|||||||
|
|
||||||
p.p = puddle.NewPool(
|
p.p = puddle.NewPool(
|
||||||
func(ctx context.Context) (interface{}, error) {
|
func(ctx context.Context) (interface{}, error) {
|
||||||
|
// we ignore cancellation on the original context because its either from
|
||||||
|
// the health check or its from a query and we don't want to cancel creating
|
||||||
|
// a connection just because the original query was cancelled since that
|
||||||
|
// could end up stampeding the server
|
||||||
|
// this will keep any Values in the original context and will just ignore
|
||||||
|
// cancellation
|
||||||
|
// see https://github.com/jackc/pgx/issues/1259
|
||||||
|
ctx = detachedCtx{ctx}
|
||||||
connConfig := p.config.ConnConfig
|
connConfig := p.config.ConnConfig
|
||||||
|
|
||||||
if p.beforeConnect != nil {
|
if p.beforeConnect != nil {
|
||||||
|
|||||||
@@ -73,6 +73,33 @@ func TestLazyConnect(t *testing.T) {
|
|||||||
assert.Equal(t, context.Canceled, err)
|
assert.Equal(t, context.Canceled, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestConstructorIgnoresContext(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
config, err := pgxpool.ParseConfig(os.Getenv("PGX_TEST_DATABASE"))
|
||||||
|
assert.NoError(t, err)
|
||||||
|
config.LazyConnect = true
|
||||||
|
var cancel func()
|
||||||
|
config.BeforeConnect = func(context.Context, *pgx.ConnConfig) error {
|
||||||
|
// cancel the query's context before we actually Dial to ensure the Dial's
|
||||||
|
// context isn't cancelled
|
||||||
|
cancel()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
pool, err := pgxpool.ConnectConfig(context.Background(), config)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
assert.EqualValues(t, 0, pool.Stat().TotalConns())
|
||||||
|
|
||||||
|
var ctx context.Context
|
||||||
|
ctx, cancel = context.WithCancel(context.Background())
|
||||||
|
defer cancel()
|
||||||
|
_, err = pool.Exec(ctx, "SELECT 1")
|
||||||
|
assert.ErrorIs(t, err, context.Canceled)
|
||||||
|
assert.EqualValues(t, 1, pool.Stat().TotalConns())
|
||||||
|
}
|
||||||
|
|
||||||
func TestConnectConfigRequiresConnConfigFromParseConfig(t *testing.T) {
|
func TestConnectConfigRequiresConnConfigFromParseConfig(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user