Spanner: prevent rpc timeouts in replenishPool
The RPC's in replenishPool used the context with timeout that was
passed in by the maintainer method. By default, this would have a
timeout of 1 minute, but can be configured to a different value.
This timeout value should not be used to timeout the gRPC calls,
as a very low value would start timing out all or most gRPC calls
for creating and deleting sessions in replenishPool, causing the
method to report a lot of timeout error and preventing it from
executing its actual task. The TestStressSessionPool tests the
session pool with different configurations. One of them is with a
healthCheckSampleInterval of 10ms, which currently fills up the
test log with a large number of timeout errors (when executed
with the -race argument).
Change-Id: I47bb58185f2f9768dc96aa50e2c420cbe31bac7a
Reviewed-on: https://code-review.googlesource.com/c/gocloud/+/44177
Reviewed-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Jean de Klerk <deklerk@google.com>
diff --git a/spanner/session.go b/spanner/session.go
index 27bad1b..20329c3 100644
--- a/spanner/session.go
+++ b/spanner/session.go
@@ -1115,16 +1115,22 @@
s *session
err error
)
- if s, err = p.createSession(ctx); err != nil {
+ createContext, cancel := context.WithTimeout(context.Background(), time.Minute)
+ if s, err = p.createSession(createContext); err != nil {
+ cancel()
log.Printf("Failed to create session, error: %v", toSpannerError(err))
continue
}
+ cancel()
if shouldPrepareWrite {
- if err = s.prepareForWrite(ctx); err != nil {
+ prepareContext, cancel := context.WithTimeout(context.Background(), time.Minute)
+ if err = s.prepareForWrite(prepareContext); err != nil {
+ cancel()
p.recycle(s)
log.Printf("Failed to prepare session, error: %v", toSpannerError(err))
continue
}
+ cancel()
}
p.recycle(s)
}