Skip to content

issue 1062: Keep track of (context cancelled) error on connection, and make rows.Next return it - #1064

Merged
otan merged 7 commits into
lib:masterfrom
mjl-:1062-QueryRowContext-ErrBadConn-fix
Nov 8, 2021
Merged

issue 1062: Keep track of (context cancelled) error on connection, and make rows.Next return it#1064
otan merged 7 commits into
lib:masterfrom
mjl-:1062-QueryRowContext-ErrBadConn-fix

Conversation

@mjl-

@mjl- mjl- commented Oct 19, 2021

Copy link
Copy Markdown
Contributor

For #1062

Instead of just whether the connection is ErrBadConn. Often times, the error
will still be ErrBadConn. But for expired/cancelled contexts, it will be the
error for the context. Most functions still return ErrBadConn per the
database/sql/driver contract ("ErrBadConn should only be returned from [...] a
query method"). For rows.Next() we return the context-related error.

The database/sql/driver contract doesn't look very precise. Is Next a "query
method" and should database/sql handle ErrBadConns when Next returns them?

Do we have more functions that should return the canceled-context error
message?

mjl- added 2 commits October 19, 2021 15:12
Instead of just whether the connection is ErrBadConn. Often times, the error
will still be ErrBadConn. But for expired/cancelled contexts, it will be the
error for the context. Most functions still return ErrBadConn per the
database/sql/driver contract ("ErrBadConn should only be returned from [...] a
query method"). For rows.Next() we return the context-related error.

The database/sql/driver contract doesn't look very precise. Is Next a "query
method" and should database/sql handle ErrBadConns when Next returns them?

Do we have more functions that should return the canceled-context error
message?

@otan otan left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i don't check this repo often, sorry for the super slow reply (you'll need to ping me if its >24 business hours)

have a couple of cleanup suggestions for you

Comment thread conn.go
}

type syncErr struct {
err error

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any reason not to use type syncErr atomic.Value here, avoiding the mutex in the impls below?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIRC, I tried and ran into not being able to store a nil value. I currently don't see the code storing nil though, so I could have run into it while testing only. I'll give it a try.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah, the actual reason is that syncErr.set only wants to set an error if it is currently nil. atomic.Value's CompareAndSwap was introduced only in go1.17.

Comment thread conn_test.go Outdated
t.Fatalf("expected driver.ErrBadConn, got: %#v", err)
}
if !cn.getBad() {
if err := cn.err.get(); err == nil {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should assert what kind of error gets returned here

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

Comment thread conn_test.go Outdated
t.Fatalf("expected driver.ErrBadConn, got: %#v", err)
}
if !cn.getBad() {
if err := cn.err.get(); err == nil {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here too

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also fixed

Comment thread copy.go Outdated
closed bool

sync.Mutex // guards err
sync.Mutex // guards err and Result

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

whilst you're here, can you make this easier to not make a mistake by going:

type copyin struct {
  // ....
  type mu struct {
     sync.Mutex
     driver.Result
     err error
  }
}

then use

var c copyin
c.mu.Lock() ....
c.mu.Result() ...

that way it's clear how the mutex is used.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i added the mu struct. by making the err & Result available under a different name, and fixing the uses, i noticed the usage wasn't correct.

Comment thread issues_test.go Outdated
@otan

otan commented Nov 7, 2021

Copy link
Copy Markdown
Collaborator

looks like this is also failing tests

@mjl-

mjl- commented Nov 8, 2021

Copy link
Copy Markdown
Contributor Author

The failed error was due to existing checks around "context canceled" not handling the error.
Those places still check for driver.ErrBadConn. I'll look into if I can remove those errors there.

I'll also look into your other cleanup suggestions. Hopefully within the next few days.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

2 participants