Revert nil context support

query-exec-mode
bakape 2020-01-11 16:53:50 +02:00
parent 9372218107
commit 9decdbc2ec
6 changed files with 731 additions and 883 deletions

View File

@ -11,13 +11,13 @@ low-level access to PostgreSQL functionality.
## Example Usage
```go
pgConn, err := pgconn.Connect(nil, os.Getenv("DATABASE_URL"))
pgConn, err := pgconn.Connect(context.Background(), os.Getenv("DATABASE_URL"))
if err != nil {
log.Fatalln("pgconn failed to connect:", err)
}
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() {
fmt.Println("User 123 has email:", string(result.Values()[0]))
}

View File

@ -14,16 +14,9 @@ func BenchmarkConnect(b *testing.B) {
benchmarks := []struct {
name string
env string
ctx context.Context
}{
// The first benchmark in the list sometimes executes faster, no matter how
// you reorder it. Nil context is still faster on average.
//
// 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},
{"Unix socket", "PGX_TEST_UNIX_SOCKET_CONN_STRING"},
{"TCP", "PGX_TEST_TCP_CONN_STRING"},
}
for _, bm := range benchmarks {
@ -35,10 +28,10 @@ func BenchmarkConnect(b *testing.B) {
}
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)
err = conn.Close(bm.ctx)
err = conn.Close(context.Background())
require.Nil(b, err)
}
})
@ -51,9 +44,10 @@ func BenchmarkExec(b *testing.B) {
name string
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()},
{"nil context", nil},
}
for _, bm := range benchmarks {
@ -156,9 +150,10 @@ func BenchmarkExecPrepared(b *testing.B) {
name string
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()},
{"nil context", nil},
}
for _, bm := range benchmarks {

1
doc.go
View File

@ -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
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
client to abort.

View File

@ -29,25 +29,3 @@ func ensureConnValid(t *testing.T, pgConn *pgconn.PgConn) {
assert.Equal(t, "2", string(result.Rows[1][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)
})
}
}

View File

@ -116,10 +116,6 @@ func ConnectConfig(ctx context.Context, config *Config) (pgConn *PgConn, err err
panic("config must be created by ParseConfig")
}
if ctx == nil {
ctx = context.Background()
}
// Simplify usage by treating primary config and fallbacks the same.
fallbackConfigs := []*FallbackConfig{
{
@ -366,9 +362,7 @@ func (pgConn *PgConn) SendBytes(ctx context.Context, buf []byte) error {
}
defer pgConn.unlock()
switch ctx {
case nil, context.Background():
default:
if ctx != context.Background() {
select {
case <-ctx.Done():
return &contextAlreadyDoneError{err: ctx.Err()}
@ -400,9 +394,7 @@ func (pgConn *PgConn) ReceiveMessage(ctx context.Context) (pgproto3.BackendMessa
}
defer pgConn.unlock()
switch ctx {
case nil, context.Background():
default:
if ctx != context.Background() {
select {
case <-ctx.Done():
return nil, &contextAlreadyDoneError{err: ctx.Err()}
@ -501,9 +493,7 @@ func (pgConn *PgConn) Close(ctx context.Context) error {
defer pgConn.conn.Close()
switch ctx {
case nil, context.Background():
default:
if ctx != context.Background() {
pgConn.contextWatcher.Watch(ctx)
defer pgConn.contextWatcher.Unwatch()
}
@ -602,9 +592,7 @@ func (pgConn *PgConn) Prepare(ctx context.Context, name, sql string, paramOIDs [
}
defer pgConn.unlock()
switch ctx {
case nil, context.Background():
default:
if ctx != context.Background() {
select {
case <-ctx.Done():
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
// specified or DNS may be used to load balance.
serverAddr := pgConn.conn.RemoteAddr()
_ctx := ctx
if _ctx == nil {
_ctx = context.Background()
}
cancelConn, err := pgConn.config.DialFunc(_ctx, serverAddr.Network(), serverAddr.String())
cancelConn, err := pgConn.config.DialFunc(ctx, serverAddr.Network(), serverAddr.String())
if err != nil {
return err
}
defer cancelConn.Close()
switch ctx {
case nil, context.Background():
default:
if ctx != context.Background() {
contextWatcher := ctxwatch.NewContextWatcher(
func() { cancelConn.SetDeadline(time.Date(1, 1, 1, 1, 1, 1, 1, time.UTC)) },
func() { cancelConn.SetDeadline(time.Time{}) },
@ -740,9 +722,7 @@ func (pgConn *PgConn) WaitForNotification(ctx context.Context) error {
}
defer pgConn.unlock()
switch ctx {
case nil, context.Background():
default:
if ctx != context.Background() {
select {
case <-ctx.Done():
return ctx.Err()
@ -784,11 +764,7 @@ func (pgConn *PgConn) Exec(ctx context.Context, sql string) *MultiResultReader {
ctx: ctx,
}
multiResult := &pgConn.multiResultReader
switch ctx {
case nil:
pgConn.multiResultReader.ctx = context.Background()
case context.Background():
default:
if ctx != context.Background() {
select {
case <-ctx.Done():
multiResult.closed = true
@ -882,9 +858,6 @@ func (pgConn *PgConn) execExtendedPrefix(ctx context.Context, paramValues [][]by
ctx: ctx,
}
result := &pgConn.resultReader
if ctx == nil {
pgConn.resultReader.ctx = context.Background()
}
if err := pgConn.lock(); err != nil {
result.concludeCommand(nil, err)
@ -899,9 +872,7 @@ func (pgConn *PgConn) execExtendedPrefix(ctx context.Context, paramValues [][]by
return result
}
switch ctx {
case nil, context.Background():
default:
if ctx != context.Background() {
select {
case <-ctx.Done():
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
}
switch ctx {
case nil, context.Background():
default:
if ctx != context.Background() {
select {
case <-ctx.Done():
pgConn.unlock()
@ -1000,9 +969,7 @@ func (pgConn *PgConn) CopyFrom(ctx context.Context, r io.Reader, sql string) (Co
}
defer pgConn.unlock()
switch ctx {
case nil, context.Background():
default:
if ctx != context.Background() {
select {
case <-ctx.Done():
return nil, &contextAlreadyDoneError{err: ctx.Err()}
@ -1396,11 +1363,8 @@ func (pgConn *PgConn) ExecBatch(ctx context.Context, batch *Batch) *MultiResultR
ctx: ctx,
}
multiResult := &pgConn.multiResultReader
switch ctx {
case nil:
pgConn.multiResultReader.ctx = context.Background()
case context.Background():
default:
if ctx != context.Background() {
select {
case <-ctx.Done():
multiResult.closed = true

File diff suppressed because it is too large Load Diff