2
0

Don't synchronize with context.Background()

This commit is contained in:
bakape
2020-01-01 19:34:56 +02:00
parent 4d345164f1
commit 9372218107
3 changed files with 46 additions and 22 deletions
+8 -4
View File
@@ -18,8 +18,10 @@ func BenchmarkConnect(b *testing.B) {
}{ }{
// The first benchmark in the list sometimes executes faster, no matter how // The first benchmark in the list sometimes executes faster, no matter how
// you reorder it. Nil context is still faster on average. // you reorder it. Nil context is still faster on average.
{"Unix socket", "PGX_TEST_UNIX_SOCKET_CONN_STRING", context.Background()}, //
{"TCP", "PGX_TEST_TCP_CONN_STRING", context.Background()}, // 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}, {"Unix socket nil context", "PGX_TEST_UNIX_SOCKET_CONN_STRING", nil},
{"TCP nil context", "PGX_TEST_TCP_CONN_STRING", nil}, {"TCP nil context", "PGX_TEST_TCP_CONN_STRING", nil},
} }
@@ -49,7 +51,8 @@ func BenchmarkExec(b *testing.B) {
name string name string
ctx context.Context ctx context.Context
}{ }{
{"background context", context.Background()}, // Using and empty context other than context.Background() to compare.
{"empty context", context.TODO()},
{"nil context", nil}, {"nil context", nil},
} }
@@ -153,7 +156,8 @@ func BenchmarkExecPrepared(b *testing.B) {
name string name string
ctx context.Context ctx context.Context
}{ }{
{"background context", context.Background()}, // Using and empty context other than context.Background() to compare.
{"empty context", context.TODO()},
{"nil context", nil}, {"nil context", nil},
} }
+1 -3
View File
@@ -22,9 +22,7 @@ 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().
A nil context can be passed for convenience. This has the same effect as passing context.Background() with an additional
slight performance increase, if you don't need the operation to be cancellable.
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.
+37 -15
View File
@@ -366,7 +366,9 @@ func (pgConn *PgConn) SendBytes(ctx context.Context, buf []byte) error {
} }
defer pgConn.unlock() defer pgConn.unlock()
if ctx != nil { switch ctx {
case nil, context.Background():
default:
select { select {
case <-ctx.Done(): case <-ctx.Done():
return &contextAlreadyDoneError{err: ctx.Err()} return &contextAlreadyDoneError{err: ctx.Err()}
@@ -398,7 +400,9 @@ func (pgConn *PgConn) ReceiveMessage(ctx context.Context) (pgproto3.BackendMessa
} }
defer pgConn.unlock() defer pgConn.unlock()
if ctx != nil { switch ctx {
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()}
@@ -497,7 +501,9 @@ func (pgConn *PgConn) Close(ctx context.Context) error {
defer pgConn.conn.Close() defer pgConn.conn.Close()
if ctx != nil { switch ctx {
case nil, context.Background():
default:
pgConn.contextWatcher.Watch(ctx) pgConn.contextWatcher.Watch(ctx)
defer pgConn.contextWatcher.Unwatch() defer pgConn.contextWatcher.Unwatch()
} }
@@ -596,7 +602,9 @@ func (pgConn *PgConn) Prepare(ctx context.Context, name, sql string, paramOIDs [
} }
defer pgConn.unlock() defer pgConn.unlock()
if ctx != nil { switch ctx {
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()}
@@ -695,7 +703,9 @@ func (pgConn *PgConn) CancelRequest(ctx context.Context) error {
} }
defer cancelConn.Close() defer cancelConn.Close()
if ctx != nil { switch ctx {
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{}) },
@@ -730,7 +740,9 @@ func (pgConn *PgConn) WaitForNotification(ctx context.Context) error {
} }
defer pgConn.unlock() defer pgConn.unlock()
if ctx != nil { switch ctx {
case nil, context.Background():
default:
select { select {
case <-ctx.Done(): case <-ctx.Done():
return ctx.Err() return ctx.Err()
@@ -772,7 +784,11 @@ func (pgConn *PgConn) Exec(ctx context.Context, sql string) *MultiResultReader {
ctx: ctx, ctx: ctx,
} }
multiResult := &pgConn.multiResultReader multiResult := &pgConn.multiResultReader
if ctx != nil { switch ctx {
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
@@ -782,8 +798,6 @@ func (pgConn *PgConn) Exec(ctx context.Context, sql string) *MultiResultReader {
default: default:
} }
pgConn.contextWatcher.Watch(ctx) pgConn.contextWatcher.Watch(ctx)
} else {
pgConn.multiResultReader.ctx = context.Background()
} }
buf := pgConn.wbuf buf := pgConn.wbuf
@@ -885,7 +899,9 @@ func (pgConn *PgConn) execExtendedPrefix(ctx context.Context, paramValues [][]by
return result return result
} }
if ctx != nil { switch ctx {
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()})
@@ -921,7 +937,9 @@ func (pgConn *PgConn) CopyTo(ctx context.Context, w io.Writer, sql string) (Comm
return nil, err return nil, err
} }
if ctx != nil { switch ctx {
case nil, context.Background():
default:
select { select {
case <-ctx.Done(): case <-ctx.Done():
pgConn.unlock() pgConn.unlock()
@@ -982,7 +1000,9 @@ func (pgConn *PgConn) CopyFrom(ctx context.Context, r io.Reader, sql string) (Co
} }
defer pgConn.unlock() defer pgConn.unlock()
if ctx != nil { switch ctx {
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()}
@@ -1376,7 +1396,11 @@ func (pgConn *PgConn) ExecBatch(ctx context.Context, batch *Batch) *MultiResultR
ctx: ctx, ctx: ctx,
} }
multiResult := &pgConn.multiResultReader multiResult := &pgConn.multiResultReader
if ctx != nil { switch ctx {
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
@@ -1386,8 +1410,6 @@ func (pgConn *PgConn) ExecBatch(ctx context.Context, batch *Batch) *MultiResultR
default: default:
} }
pgConn.contextWatcher.Watch(ctx) pgConn.contextWatcher.Watch(ctx)
} else {
pgConn.multiResultReader.ctx = context.Background()
} }
batch.buf = (&pgproto3.Sync{}).Encode(batch.buf) batch.buf = (&pgproto3.Sync{}).Encode(batch.buf)