-
Notifications
You must be signed in to change notification settings - Fork 4.5k
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
transport: refactor of error/cancellation paths #1533
Conversation
scheme := "http" | ||
conn, err := dial(ctx, opts.Dialer, addr.Addr) | ||
ctx, cancel := context.WithCancel(ctx) | ||
connectCtx, connectCancel := context.WithTimeout(ctx, 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.
Move these two cancel functions to a defer
defer func() {
if err != nil {
cancel()
// Don't call connectCancel in success path due to a race in Go 1.6:
 // https://github.com/golang/go/issues/15078.
connectCancel()
}
}
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. The reason the conn is passed in the defer below, BTW, is because if ClientHandshake encounters an error, conn would probably be nil. I tried to clean this up, but it's a slippery slope and the diffs start looking much bigger. I'll wait until later and only do what you asked for now.
@@ -601,7 +608,7 @@ func (t *http2Client) Close() (err error) { | |||
} |
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.
This if
will always be true. The only other state is unreachable
set by notifyError, and that code was deleted.
Actually, is errorChan === t.ctx.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.
Removed the if, and unreachable entirely.
Yes, errorChan is essentially t.ctx.Done(), with only subtly different semantics that were irrelevant. Removed. Good catch.
Conflicts... Also, should we label this PR as an API change? Even though it's an internal API change? |
a70c753
to
d0d2db3
Compare
Resolved.
I don't think so. I think the labels on PRs should be applied so that end users can understand the release notes. If we put non-user-impacting API changes in with ones that do impact users, that dilutes the significance of the section. |
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.
LGTM 💪
- The transport is now responsible for closing its own connection when an error occurs or when the context given to it in NewClientTransport() is canceled. - Remove client/server shutdown channels -- add cancel function to allow self-cancellation. - Plumb the clientConn's context into the client transport to allow for the transport to be canceled even after it has been removed from the ac (due to graceful close) when the ClientConn is closed.
d0d2db3
to
6de94a3
Compare
@@ -65,7 +65,7 @@ git ls-files "*.go" | xargs sed -i 's:"golang.org/x/net/context":"context":' | |||
set +o pipefail | |||
# TODO: Stop filtering pb.go files once golang/protobuf#214 is fixed. | |||
# TODO: Remove clientconn exception once go1.6 support is removed. |
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.
looks like you addressed this TODO.
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 comment was removed when Go1.6 support was removed.
// If it receives from proceed, it returns the received integer, nil. | ||
func wait(ctx context.Context, done, goAway, closing <-chan struct{}, proceed <-chan int) (int, error) { | ||
// wait blocks until it can receive from one of the provided contexts or channels | ||
func wait(ctx, tctx context.Context, done, goAway <-chan struct{}, proceed <-chan int) (int, error) { |
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.
what is tctx
? the name leaves something to be desired and the doc comment doesn't explain it.
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.
t=transport. I'll add a comment. I wasn't a big fan of this function in the first place, but I decided to keep it (for now anyway).
default: | ||
errorf("transport: http2Server.controller got unexpected item type %v\n", i) | ||
err := status.Errorf(codes.Internal, "transport: http2Server.controller got unexpected item type %t\n", i) |
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 believe it's conventional to omit trailing newlines in error strings.
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.
This was fixed by #1553.
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.
Thanks for taking a look.
default: | ||
errorf("transport: http2Server.controller got unexpected item type %v\n", i) | ||
err := status.Errorf(codes.Internal, "transport: http2Server.controller got unexpected item type %t\n", i) |
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.
This was fixed by #1553.
// If it receives from proceed, it returns the received integer, nil. | ||
func wait(ctx context.Context, done, goAway, closing <-chan struct{}, proceed <-chan int) (int, error) { | ||
// wait blocks until it can receive from one of the provided contexts or channels | ||
func wait(ctx, tctx context.Context, done, goAway <-chan struct{}, proceed <-chan int) (int, error) { |
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.
t=transport. I'll add a comment. I wasn't a big fan of this function in the first place, but I decided to keep it (for now anyway).
@@ -65,7 +65,7 @@ git ls-files "*.go" | xargs sed -i 's:"golang.org/x/net/context":"context":' | |||
set +o pipefail | |||
# TODO: Stop filtering pb.go files once golang/protobuf#214 is fixed. | |||
# TODO: Remove clientconn exception once go1.6 support is removed. |
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 comment was removed when Go1.6 support was removed.
The transport is now responsible for closing its own connection when an error
occurs or when the context given to it in NewClientTransport() is canceled.
Remove client/server shutdown channels -- add cancel function to allow
self-cancellation.
Plumb the clientConn's context into the client transport to allow for the
transport to be canceled even after it has been removed from the ac (due to
graceful close) when the ClientConn is closed.
This is pre-work for fixing #1532 and implementing transparent retries.