mirror of https://github.com/jackc/pgx.git
Revert nil context support
parent
9372218107
commit
9decdbc2ec
|
@ -11,13 +11,13 @@ low-level access to PostgreSQL functionality.
|
||||||
## Example Usage
|
## Example Usage
|
||||||
|
|
||||||
```go
|
```go
|
||||||
pgConn, err := pgconn.Connect(nil, os.Getenv("DATABASE_URL"))
|
pgConn, err := pgconn.Connect(context.Background(), os.Getenv("DATABASE_URL"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalln("pgconn failed to connect:", err)
|
log.Fatalln("pgconn failed to connect:", err)
|
||||||
}
|
}
|
||||||
defer pgConn.Close()
|
defer pgConn.Close()
|
||||||
|
|
||||||
result := pgConn.ExecParams(nil, "SELECT email FROM users WHERE id=$1", [][]byte{[]byte("123")}, nil, nil, nil)
|
result := pgConn.ExecParams(context.Background(), "SELECT email FROM users WHERE id=$1", [][]byte{[]byte("123")}, nil, nil, nil)
|
||||||
for result.NextRow() {
|
for result.NextRow() {
|
||||||
fmt.Println("User 123 has email:", string(result.Values()[0]))
|
fmt.Println("User 123 has email:", string(result.Values()[0]))
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,16 +14,9 @@ func BenchmarkConnect(b *testing.B) {
|
||||||
benchmarks := []struct {
|
benchmarks := []struct {
|
||||||
name string
|
name string
|
||||||
env string
|
env string
|
||||||
ctx context.Context
|
|
||||||
}{
|
}{
|
||||||
// The first benchmark in the list sometimes executes faster, no matter how
|
{"Unix socket", "PGX_TEST_UNIX_SOCKET_CONN_STRING"},
|
||||||
// you reorder it. Nil context is still faster on average.
|
{"TCP", "PGX_TEST_TCP_CONN_STRING"},
|
||||||
//
|
|
||||||
// Using and empty context other than context.Background() to compare.
|
|
||||||
{"Unix socket", "PGX_TEST_UNIX_SOCKET_CONN_STRING", context.TODO()},
|
|
||||||
{"TCP", "PGX_TEST_TCP_CONN_STRING", context.TODO()},
|
|
||||||
{"Unix socket nil context", "PGX_TEST_UNIX_SOCKET_CONN_STRING", nil},
|
|
||||||
{"TCP nil context", "PGX_TEST_TCP_CONN_STRING", nil},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, bm := range benchmarks {
|
for _, bm := range benchmarks {
|
||||||
|
@ -35,10 +28,10 @@ func BenchmarkConnect(b *testing.B) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
conn, err := pgconn.Connect(bm.ctx, connString)
|
conn, err := pgconn.Connect(context.Background(), connString)
|
||||||
require.Nil(b, err)
|
require.Nil(b, err)
|
||||||
|
|
||||||
err = conn.Close(bm.ctx)
|
err = conn.Close(context.Background())
|
||||||
require.Nil(b, err)
|
require.Nil(b, err)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -51,9 +44,10 @@ func BenchmarkExec(b *testing.B) {
|
||||||
name string
|
name string
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
}{
|
}{
|
||||||
// Using and empty context other than context.Background() to compare.
|
// Using an empty context other than context.Background() to compare
|
||||||
|
// performance
|
||||||
|
{"background context", context.Background()},
|
||||||
{"empty context", context.TODO()},
|
{"empty context", context.TODO()},
|
||||||
{"nil context", nil},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, bm := range benchmarks {
|
for _, bm := range benchmarks {
|
||||||
|
@ -156,9 +150,10 @@ func BenchmarkExecPrepared(b *testing.B) {
|
||||||
name string
|
name string
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
}{
|
}{
|
||||||
// Using and empty context other than context.Background() to compare.
|
// Using an empty context other than context.Background() to compare
|
||||||
|
// performance
|
||||||
|
{"background context", context.Background()},
|
||||||
{"empty context", context.TODO()},
|
{"empty context", context.TODO()},
|
||||||
{"nil context", nil},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, bm := range benchmarks {
|
for _, bm := range benchmarks {
|
||||||
|
|
1
doc.go
1
doc.go
|
@ -22,7 +22,6 @@ Context Support
|
||||||
|
|
||||||
All potentially blocking operations take a context.Context. If a context is canceled while the method is in progress the
|
All potentially blocking operations take a context.Context. If a context is canceled while the method is in progress the
|
||||||
method immediately returns. In most circumstances, this will close the underlying connection.
|
method immediately returns. In most circumstances, this will close the underlying connection.
|
||||||
A nil context can be passed for convenience. This has the same effect as passing context.Background().
|
|
||||||
|
|
||||||
The CancelRequest method may be used to request the PostgreSQL server cancel an in-progress query without forcing the
|
The CancelRequest method may be used to request the PostgreSQL server cancel an in-progress query without forcing the
|
||||||
client to abort.
|
client to abort.
|
||||||
|
|
|
@ -29,25 +29,3 @@ func ensureConnValid(t *testing.T, pgConn *pgconn.PgConn) {
|
||||||
assert.Equal(t, "2", string(result.Rows[1][0]))
|
assert.Equal(t, "2", string(result.Rows[1][0]))
|
||||||
assert.Equal(t, "3", string(result.Rows[2][0]))
|
assert.Equal(t, "3", string(result.Rows[2][0]))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run subtest both with a context.Background() and nil context
|
|
||||||
func splitOnContext(t *testing.T, test func(t *testing.T, ctx context.Context)) {
|
|
||||||
t.Helper()
|
|
||||||
|
|
||||||
cases := [...]struct {
|
|
||||||
name string
|
|
||||||
ctx context.Context
|
|
||||||
}{
|
|
||||||
{"background context", context.Background()},
|
|
||||||
{"nil context", nil},
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := range cases {
|
|
||||||
c := cases[i]
|
|
||||||
t.Run(c.name, func(t *testing.T) {
|
|
||||||
t.Helper()
|
|
||||||
t.Parallel()
|
|
||||||
test(t, c.ctx)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
62
pgconn.go
62
pgconn.go
|
@ -116,10 +116,6 @@ func ConnectConfig(ctx context.Context, config *Config) (pgConn *PgConn, err err
|
||||||
panic("config must be created by ParseConfig")
|
panic("config must be created by ParseConfig")
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx == nil {
|
|
||||||
ctx = context.Background()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Simplify usage by treating primary config and fallbacks the same.
|
// Simplify usage by treating primary config and fallbacks the same.
|
||||||
fallbackConfigs := []*FallbackConfig{
|
fallbackConfigs := []*FallbackConfig{
|
||||||
{
|
{
|
||||||
|
@ -366,9 +362,7 @@ func (pgConn *PgConn) SendBytes(ctx context.Context, buf []byte) error {
|
||||||
}
|
}
|
||||||
defer pgConn.unlock()
|
defer pgConn.unlock()
|
||||||
|
|
||||||
switch ctx {
|
if ctx != context.Background() {
|
||||||
case nil, context.Background():
|
|
||||||
default:
|
|
||||||
select {
|
select {
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
return &contextAlreadyDoneError{err: ctx.Err()}
|
return &contextAlreadyDoneError{err: ctx.Err()}
|
||||||
|
@ -400,9 +394,7 @@ func (pgConn *PgConn) ReceiveMessage(ctx context.Context) (pgproto3.BackendMessa
|
||||||
}
|
}
|
||||||
defer pgConn.unlock()
|
defer pgConn.unlock()
|
||||||
|
|
||||||
switch ctx {
|
if ctx != context.Background() {
|
||||||
case nil, context.Background():
|
|
||||||
default:
|
|
||||||
select {
|
select {
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
return nil, &contextAlreadyDoneError{err: ctx.Err()}
|
return nil, &contextAlreadyDoneError{err: ctx.Err()}
|
||||||
|
@ -501,9 +493,7 @@ func (pgConn *PgConn) Close(ctx context.Context) error {
|
||||||
|
|
||||||
defer pgConn.conn.Close()
|
defer pgConn.conn.Close()
|
||||||
|
|
||||||
switch ctx {
|
if ctx != context.Background() {
|
||||||
case nil, context.Background():
|
|
||||||
default:
|
|
||||||
pgConn.contextWatcher.Watch(ctx)
|
pgConn.contextWatcher.Watch(ctx)
|
||||||
defer pgConn.contextWatcher.Unwatch()
|
defer pgConn.contextWatcher.Unwatch()
|
||||||
}
|
}
|
||||||
|
@ -602,9 +592,7 @@ func (pgConn *PgConn) Prepare(ctx context.Context, name, sql string, paramOIDs [
|
||||||
}
|
}
|
||||||
defer pgConn.unlock()
|
defer pgConn.unlock()
|
||||||
|
|
||||||
switch ctx {
|
if ctx != context.Background() {
|
||||||
case nil, context.Background():
|
|
||||||
default:
|
|
||||||
select {
|
select {
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
return nil, &contextAlreadyDoneError{err: ctx.Err()}
|
return nil, &contextAlreadyDoneError{err: ctx.Err()}
|
||||||
|
@ -693,19 +681,13 @@ func (pgConn *PgConn) CancelRequest(ctx context.Context) error {
|
||||||
// the connection config. This is important in high availability configurations where fallback connections may be
|
// the connection config. This is important in high availability configurations where fallback connections may be
|
||||||
// specified or DNS may be used to load balance.
|
// specified or DNS may be used to load balance.
|
||||||
serverAddr := pgConn.conn.RemoteAddr()
|
serverAddr := pgConn.conn.RemoteAddr()
|
||||||
_ctx := ctx
|
cancelConn, err := pgConn.config.DialFunc(ctx, serverAddr.Network(), serverAddr.String())
|
||||||
if _ctx == nil {
|
|
||||||
_ctx = context.Background()
|
|
||||||
}
|
|
||||||
cancelConn, err := pgConn.config.DialFunc(_ctx, serverAddr.Network(), serverAddr.String())
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer cancelConn.Close()
|
defer cancelConn.Close()
|
||||||
|
|
||||||
switch ctx {
|
if ctx != context.Background() {
|
||||||
case nil, context.Background():
|
|
||||||
default:
|
|
||||||
contextWatcher := ctxwatch.NewContextWatcher(
|
contextWatcher := ctxwatch.NewContextWatcher(
|
||||||
func() { cancelConn.SetDeadline(time.Date(1, 1, 1, 1, 1, 1, 1, time.UTC)) },
|
func() { cancelConn.SetDeadline(time.Date(1, 1, 1, 1, 1, 1, 1, time.UTC)) },
|
||||||
func() { cancelConn.SetDeadline(time.Time{}) },
|
func() { cancelConn.SetDeadline(time.Time{}) },
|
||||||
|
@ -740,9 +722,7 @@ func (pgConn *PgConn) WaitForNotification(ctx context.Context) error {
|
||||||
}
|
}
|
||||||
defer pgConn.unlock()
|
defer pgConn.unlock()
|
||||||
|
|
||||||
switch ctx {
|
if ctx != context.Background() {
|
||||||
case nil, context.Background():
|
|
||||||
default:
|
|
||||||
select {
|
select {
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
return ctx.Err()
|
return ctx.Err()
|
||||||
|
@ -784,11 +764,7 @@ func (pgConn *PgConn) Exec(ctx context.Context, sql string) *MultiResultReader {
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
}
|
}
|
||||||
multiResult := &pgConn.multiResultReader
|
multiResult := &pgConn.multiResultReader
|
||||||
switch ctx {
|
if ctx != context.Background() {
|
||||||
case nil:
|
|
||||||
pgConn.multiResultReader.ctx = context.Background()
|
|
||||||
case context.Background():
|
|
||||||
default:
|
|
||||||
select {
|
select {
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
multiResult.closed = true
|
multiResult.closed = true
|
||||||
|
@ -882,9 +858,6 @@ func (pgConn *PgConn) execExtendedPrefix(ctx context.Context, paramValues [][]by
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
}
|
}
|
||||||
result := &pgConn.resultReader
|
result := &pgConn.resultReader
|
||||||
if ctx == nil {
|
|
||||||
pgConn.resultReader.ctx = context.Background()
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := pgConn.lock(); err != nil {
|
if err := pgConn.lock(); err != nil {
|
||||||
result.concludeCommand(nil, err)
|
result.concludeCommand(nil, err)
|
||||||
|
@ -899,9 +872,7 @@ func (pgConn *PgConn) execExtendedPrefix(ctx context.Context, paramValues [][]by
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
switch ctx {
|
if ctx != context.Background() {
|
||||||
case nil, context.Background():
|
|
||||||
default:
|
|
||||||
select {
|
select {
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
result.concludeCommand(nil, &contextAlreadyDoneError{err: ctx.Err()})
|
result.concludeCommand(nil, &contextAlreadyDoneError{err: ctx.Err()})
|
||||||
|
@ -937,9 +908,7 @@ func (pgConn *PgConn) CopyTo(ctx context.Context, w io.Writer, sql string) (Comm
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
switch ctx {
|
if ctx != context.Background() {
|
||||||
case nil, context.Background():
|
|
||||||
default:
|
|
||||||
select {
|
select {
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
pgConn.unlock()
|
pgConn.unlock()
|
||||||
|
@ -1000,9 +969,7 @@ func (pgConn *PgConn) CopyFrom(ctx context.Context, r io.Reader, sql string) (Co
|
||||||
}
|
}
|
||||||
defer pgConn.unlock()
|
defer pgConn.unlock()
|
||||||
|
|
||||||
switch ctx {
|
if ctx != context.Background() {
|
||||||
case nil, context.Background():
|
|
||||||
default:
|
|
||||||
select {
|
select {
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
return nil, &contextAlreadyDoneError{err: ctx.Err()}
|
return nil, &contextAlreadyDoneError{err: ctx.Err()}
|
||||||
|
@ -1396,11 +1363,8 @@ func (pgConn *PgConn) ExecBatch(ctx context.Context, batch *Batch) *MultiResultR
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
}
|
}
|
||||||
multiResult := &pgConn.multiResultReader
|
multiResult := &pgConn.multiResultReader
|
||||||
switch ctx {
|
|
||||||
case nil:
|
if ctx != context.Background() {
|
||||||
pgConn.multiResultReader.ctx = context.Background()
|
|
||||||
case context.Background():
|
|
||||||
default:
|
|
||||||
select {
|
select {
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
multiResult.closed = true
|
multiResult.closed = true
|
||||||
|
|
304
pgconn_test.go
304
pgconn_test.go
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue