Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.
Sign upFix checking cancelled connections back into the connection pool #1095
Conversation
649efc7
to
dee6989
Github didn't get the memo but if you click through to the travis build it's green. |
if err != nil { | ||
dbt.Fatal(err) | ||
} | ||
|
||
// Delay execution for just a bit until db.ExecContext has begun. | ||
defer time.AfterFunc(100*time.Millisecond, cancel).Stop() | ||
go time.AfterFunc(100*time.Millisecond, cancel) |
methane
May 12, 2020
Member
Why this change?
Why this change?
KJTsanaktsidis
May 12, 2020
Author
Contributor
I actually didn't understand how this was working at all - what it looked like it should be doing was canceling the context whilst the SQL was executing SLEEP(1)
, so I turned it into this.
I just read the docs for time.AfterFunc
more carefully and I think we can just invoke it on the main goroutine instead of calling go
?
I actually didn't understand how this was working at all - what it looked like it should be doing was canceling the context whilst the SQL was executing SLEEP(1)
, so I turned it into this.
I just read the docs for time.AfterFunc
more carefully and I think we can just invoke it on the main goroutine instead of calling go
?
KJTsanaktsidis
May 12, 2020
Author
Contributor
Eurgh - ok the problem is I just don't know how defer works. This is going to cause time.AfterFunc()
to run now, and then Stop()
to run when the method returns. I'll change it back.
Eurgh - ok the problem is I just don't know how defer works. This is going to cause time.AfterFunc()
to run now, and then Stop()
to run when the method returns. I'll change it back.
dee6989
to
1b73282
If * BeginTx is called with a non-default isolation level, * The context is canceled before SET TRANSACTION ISOLATION LEVEL completes, then the connection: * has the cancelled property set to "context cancelled", * has the closed property set to true, and, * BeginTx returns "context canceled" Because of this, the connection gets put back into the connection pool. When it is checked out again, if BeginTx is called on it again _without_ an isolation level, * then we fall into the mc.closed.IsSet() check in begin(), * so we return ErrBadConn, * so the driver kicks the broken connection out of the pool * (and transparently retries to get a new connection that isn't broken too). However, if BeginTx is called on the connection _with_ an isolation level, then we return a context canceled error from the SET TRANSACTION ISOLATION LEVEL call. That means the broken connection will stick around in the pool forever (or until it's checked out for some other operation that correctly returns ErrBadConn). The fix is to check for the connection being closed before executing SET TRANSACTION ISOLATION LEVEL.
1b73282
to
978b6bd
Thank you for a quick review & merge! |
…sql-driver#1095) If * BeginTx is called with a non-default isolation level, * The context is canceled before SET TRANSACTION ISOLATION LEVEL completes, then the connection: * has the cancelled property set to "context cancelled", * has the closed property set to true, and, * BeginTx returns "context canceled" Because of this, the connection gets put back into the connection pool. When it is checked out again, if BeginTx is called on it again _without_ an isolation level, * then we fall into the mc.closed.IsSet() check in begin(), * so we return ErrBadConn, * so the driver kicks the broken connection out of the pool * (and transparently retries to get a new connection that isn't broken too). However, if BeginTx is called on the connection _with_ an isolation level, then we return a context canceled error from the SET TRANSACTION ISOLATION LEVEL call. That means the broken connection will stick around in the pool forever (or until it's checked out for some other operation that correctly returns ErrBadConn). The fix is to check for the connection being closed before executing SET TRANSACTION ISOLATION LEVEL.
…sql-driver#1095) If * BeginTx is called with a non-default isolation level, * The context is canceled before SET TRANSACTION ISOLATION LEVEL completes, then the connection: * has the cancelled property set to "context cancelled", * has the closed property set to true, and, * BeginTx returns "context canceled" Because of this, the connection gets put back into the connection pool. When it is checked out again, if BeginTx is called on it again _without_ an isolation level, * then we fall into the mc.closed.IsSet() check in begin(), * so we return ErrBadConn, * so the driver kicks the broken connection out of the pool * (and transparently retries to get a new connection that isn't broken too). However, if BeginTx is called on the connection _with_ an isolation level, then we return a context canceled error from the SET TRANSACTION ISOLATION LEVEL call. That means the broken connection will stick around in the pool forever (or until it's checked out for some other operation that correctly returns ErrBadConn). The fix is to check for the connection being closed before executing SET TRANSACTION ISOLATION LEVEL.
Description
If
then the connection:
and,
Because of this, the connection gets put back into the connection pool. When it is checked out again, if BeginTx is called on it again without an isolation level,
However, if BeginTx is called on the connection with an isolation
level, then we return a context canceled error from the SET TRANSACTION
ISOLATION LEVEL call.
That means the broken connection will stick around in the pool forever
(or until it's checked out for some other operation that correctly
returns ErrBadConn).
The fix is to check for the connection being closed before executing SET
TRANSACTION ISOLATION LEVEL.
Checklist