-
Notifications
You must be signed in to change notification settings - Fork 915
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
Add context methods #535
Add context methods #535
Conversation
Is this WIP? |
Nope. Just waiting for reviews.
…On Thu, Dec 22, 2016, 11:10 AM Or Rikon ***@***.***> wrote:
Is this WIP?
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#535 (comment)>, or mute the
thread
<https://github.com/notifications/unsubscribe-auth/AACg3XP9FQsyLYy6R3t1TdE4uQQGAKSqks5rKr0HgaJpZM4Kq3lv>
.
|
A cancelled context will prevent new queries and halt currently running
queries.
…On Thu, Dec 22, 2016 at 1:27 PM Or Rikon ***@***.***> wrote:
@mjibson <https://github.com/mjibson> I see.
Another question - assuming I provide a context with timeout, will an
ongoing query be cancelled if the timeout is exceeded? Or is it only for
queries that are currently queued for execution?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#535 (comment)>, or mute the
thread
<https://github.com/notifications/unsubscribe-auth/AACg3cDvMRjfZpZmLeafLTgCoVm3Ounjks5rKt1AgaJpZM4Kq3lv>
.
|
To be clear, it won't cancel the queries on the server, but it will unblock
the client.
…On Dec 22, 2016 16:53, "Matt Jibson" ***@***.***> wrote:
A cancelled context will prevent new queries and halt currently running
queries.
On Thu, Dec 22, 2016 at 1:27 PM Or Rikon ***@***.***> wrote:
> @mjibson <https://github.com/mjibson> I see.
>
> Another question - assuming I provide a context with timeout, will an
> ongoing query be cancelled if the timeout is exceeded? Or is it only for
> queries that are currently queued for execution?
>
> —
> You are receiving this because you were mentioned.
>
>
> Reply to this email directly, view it on GitHub
> <#535 (comment)>, or mute the
> thread
> <https://github.com/notifications/unsubscribe-auth/
AACg3cDvMRjfZpZmLeafLTgCoVm3Ounjks5rKt1AgaJpZM4Kq3lv>
> .
>
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#535 (comment)>, or mute the
thread
<https://github.com/notifications/unsubscribe-auth/ABdsPNLGtftT6esWtPjvSseAnY1LaUvdks5rKvE9gaJpZM4Kq3lv>
.
|
Is there a reason not to add something which would send a cancel backend signal to postgres? Unless I'm misunderstanding (which I probably am), you seem to already have the PID. From there, canceling seems pretty simple. As long as you're a superuser, you could call pg_cancel_backend or pg_terminate_backend. |
No, it does indeed cancel queries on the server. See the conn.Cancel function in conn.go. It opens a new connection instructing the server to cancel the original connection. See https://www.postgresql.org/docs/current/static/protocol-flow.html#AEN112861 |
Ah, I was recalling my experiences with MySQL, disregard.
…On Dec 22, 2016 17:03, "Matt Jibson" ***@***.***> wrote:
No, it does indeed cancel queries on the server. See the conn.Cancel
function in conn.go. It opens a new connection instructing the server to
cancel the original connection. See https://www.postgresql.org/
docs/current/static/protocol-flow.html#AEN112861
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#535 (comment)>, or mute the
thread
<https://github.com/notifications/unsubscribe-auth/ABdsPEbg4zIvWVu8Otk0aVgJwHOuMcucks5rKvO8gaJpZM4Kq3lv>
.
|
conn.go
Outdated
@@ -22,6 +22,8 @@ import ( | |||
"time" | |||
"unicode" | |||
|
|||
"golang.org/x/net/context" |
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.
Is this a new dependency? If we're only using this for the interface, it would also be possible to copy just the interface definition into this package, and then avoid depending on golang.org/x/net/context.
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.
We do use it for more than just the interface: see the creations of context.Background(). However since those are empty, it seems not horrible to copy both the interface definition as you describe and the implementation for context.Background into our own file here and just use those. That would allow for not having this dependency. I've made that change.
conn.go
Outdated
w.int32(cn.secretKey) | ||
|
||
can.sendStartupPacket(w) | ||
_ = can.c.Close() |
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.
It seems wasteful to open a connection just to send one command, then immediately tear down the whole connection. Is there some way to save this conn for some time so it can potentially be used by the pool?
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.
Nope! The protocol for cancellation is to open a new connection that will immediately be closed.
conn.go
Outdated
} | ||
} | ||
|
||
if r != nil && ctx.Done() != context.Background().Done() { |
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.
It looks like this is trying to avoid the overhead of an extra goroutine in the case where the context will never be canceled. It would be better to write it as:
if r != nil && ctx.Done() != nil
Same for the other places that do this.
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.
I remember reading some stuff from that it is bad form to do ctx.Done() != nil
which is why it was done this way. But I do prefer the way you describe. Changed.
conn.go
Outdated
case <-closed: | ||
} | ||
}() | ||
r.close = closed |
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.
Maybe consider pulling this whole blob of code out into a function? It is a bit subtle, and it's repeated several times. Maybe something like:
if r != nil && ctx.Done() != nil {
r.close = watchCancel(ctx, cn.Cancel)
}
with
func watchCancel(ctx context.Context, cancel func()) chan<- struct{} {
closed := make(chan struct{})
go func() {
select {
case <-ctx.Done():
cancel()
case <-closed:
}
}()
return closed
}
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.
Done.
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.
RFAL.
Comments about the new context.go would be appreciated. Not sure if it's a good idea, but it does remove the new dependency.
conn.go
Outdated
} | ||
} | ||
|
||
if r != nil && ctx.Done() != context.Background().Done() { |
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.
I remember reading some stuff from that it is bad form to do ctx.Done() != nil
which is why it was done this way. But I do prefer the way you describe. Changed.
conn.go
Outdated
@@ -22,6 +22,8 @@ import ( | |||
"time" | |||
"unicode" | |||
|
|||
"golang.org/x/net/context" |
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.
We do use it for more than just the interface: see the creations of context.Background(). However since those are empty, it seems not horrible to copy both the interface definition as you describe and the implementation for context.Background into our own file here and just use those. That would allow for not having this dependency. I've made that change.
conn.go
Outdated
case <-closed: | ||
} | ||
}() | ||
r.close = closed |
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.
Done.
context.go
Outdated
Value(key interface{}) interface{} | ||
} | ||
|
||
type emptyCtx int |
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.
As I recall, an empty struct is actually the smallest value to have lying around.
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.
You are correct, but in order to be a more direct copy of the context code I kept it as an int: https://tip.golang.org/pkg/context/?m=all#emptyCtx
conn.go
Outdated
can := &conn{} | ||
can.c, err = dial(cn.dialer, cn.opts) | ||
if err != nil { | ||
return |
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.
Is there really nothing to be done here? Retry doesn't seem appropriate...
Is this method exported for the driver package? I don't see it in the docs.
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.
I'm not sure what else we would do. The cancellation protocol itself says that the request may or may not be successful. And it's unclear what to do in the face of network error. It doesn't seem like an error here should set an error on cn either. This is currently my best idea.
I've unexported this method.
Why do we need this "contextInterface"? If we could move all the context-related functionality under the 1.8 build tag, we could just use "context" instead. Seems like we can achieve that by having an embedded structure in Reviewed 3 of 4 files at r2. conn_go18.go, line 32 at r2 (raw file):
seems like we can support both this and the below, but i guess that's not required for this PR. go18_test.go, line 81 at r2 (raw file):
seems inherently flaky. go18_test.go, line 103 at r2 (raw file):
you need to clean up this go18_test.go, line 109 at r2 (raw file):
ditto Comments from Reviewable |
I've moved all the context stuff to a go 1.8-only file. I like this design much more. It also fleshed out a bug. Review status: 3 of 4 files reviewed at latest revision, 4 unresolved discussions. conn_go18.go, line 32 at r2 (raw file): Previously, tamird (Tamir Duberstein) wrote…
another pr for sure go18_test.go, line 81 at r2 (raw file): Previously, tamird (Tamir Duberstein) wrote…
I've added a 10ms sleep here. It's difficult to test this correctly. go18_test.go, line 103 at r2 (raw file): Previously, tamird (Tamir Duberstein) wrote…
I added leaktest to this test and it passed without any cleanup. I don't think a Tx starts any goroutines. go18_test.go, line 109 at r2 (raw file): Previously, tamird (Tamir Duberstein) wrote…
Done. Comments from Reviewable |
Let's squash this down, too. Reviewed 3 of 4 files at r3. conn.go, line 101 at r3 (raw file):
txnClosed for consistency? conn.go, line 871 at r3 (raw file):
unrelated change? conn.go, line 889 at r3 (raw file):
also unrelated? conn.go, line 1330 at r3 (raw file):
consider calling this conn_go18.go, line 18 at r3 (raw file):
move this below go18_test.go, line 103 at r2 (raw file): Previously, mjibson (Matt Jibson) wrote…
Evidence to the contrary: cockroachdb/cockroach@9bf770c Cancelling the contexts in these tests is likely what's making it work. Comments from Reviewable |
Review status: all files reviewed at latest revision, 6 unresolved discussions. conn.go, line 101 at r3 (raw file): Previously, tamird (Tamir Duberstein) wrote…
Done. conn.go, line 871 at r3 (raw file): Previously, tamird (Tamir Duberstein) wrote…
yes, removed conn.go, line 889 at r3 (raw file): Previously, tamird (Tamir Duberstein) wrote…
removed conn.go, line 1330 at r3 (raw file): Previously, tamird (Tamir Duberstein) wrote…
Done. conn_go18.go, line 18 at r3 (raw file): Previously, tamird (Tamir Duberstein) wrote…
That's how it was before, but it's a bug. We need to start the cancellation listening before the first row is returned. If this is moved below the cn.query line, then only when we have a rows object are we able to cancel a query. go18_test.go, line 103 at r2 (raw file): Previously, tamird (Tamir Duberstein) wrote…
Adding tx.Rollback() at the end produces an error: Comments from Reviewable |
Can you add 1.8.x to the travis list? In fact, all the versions should end in Reviewed 2 of 2 files at r4. conn_go18.go, line 18 at r3 (raw file): Previously, mjibson (Matt Jibson) wrote…
Ah, thanks for explaining. Comments from Reviewable |
thanks! ref #531 |
Progress on #506.
This change is![Reviewable](https://camo.githubusercontent.com/1541c4039185914e83657d3683ec25920c672c6c5c7ab4240ee7bff601adec0b/68747470733a2f2f72657669657761626c652e696f2f7265766965775f627574746f6e2e737667)