-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Treat dial error as driver.ErrBadConn #867
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Treat dial error as driver.ErrBadConn #867
Conversation
because this error is retried in the driver and means the connection never succeeded ``` // ErrBadConn should be returned by a driver to signal to the sql // package that a driver.Conn is in a bad state (such as the server // having earlier closed the connection) and the sql package should // retry on a new connection. // // To prevent duplicate operations, ErrBadConn should NOT be returned // if there's a possibility that the database server might have // performed the operation. Even if the server sends back an error, // you shouldn't return ErrBadConn. ```
In case of |
Then, we don't need to return ErrBadConn always in When we think For example, if context is canceled, we should not return ErrBadConn. |
👍 @methane I added a commit to only return |
driver.go
Outdated
@@ -77,6 +77,10 @@ func (d MySQLDriver) Open(dsn string) (driver.Conn, error) { | |||
mc.netConn, err = nd.Dial(mc.cfg.Net, mc.cfg.Addr) | |||
} | |||
if err != nil { | |||
if nerr, ok := err.(net.Error); ok && (nerr.Temporary() || nerr.Timeout()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't || nerr.Timeout()
.
nerr.Temporary()
returns True when retry is worthful.
For example, lookup timeout is temporary.
func (e *DNSError) Temporary() bool { return e.IsTimeout || e.IsTemporary }
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
the docs say
IsTimeout bool // if true, timed out; not all timeouts set this
IsTemporary bool // if true, error is temporary; not all errors set this; added in Go 1.6
so I thought it would be better to check both given IsTemporary
might not be supported
@methane is this good to be merged? |
I still dought this is worth enough to add more code to this project. |
After reading |
Description
Currently if an error happens from the
Dial()
call, there are no retries. The go sql driver will only retry on adriver.ErrBadConn
error.The following is the doc for this error:
I noticed that other functions in
MySQLDriver.Open()
already return this error, so I wonder if this was an oversight?One concern with this change is that users might be expecting and handling a
net.Error
fromdial()
, which with this PR would only be logged now.It would also be possible to handle this without changes to the lib, by using
RegisterDial()
. If we are not concerned that users might be expectingnet.Error
, I feel thatdriver.ErrBadConn
is a more appropriate error and users should't be required to useRegisterDial()
if they want retries.Checklist