Skip to content
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

Improve connection handling #231

Merged
merged 3 commits into from Aug 19, 2019

Conversation

sigurdm
Copy link
Contributor

@sigurdm sigurdm commented Aug 16, 2019

Most of this is appropriated from the grpc implementation we had in https://github.com/dart-lang/appengine. Big thanks to @mkustermann for exlpaining the intricate details!

This should make the connection handling a lot more robust, and also faster.
Hopefully dealing with: #228

if (securityContext == null) {
socket = await Socket.connect(host, port);
} else {
final socket = await SecureSocket.connect(host, port,

Choose a reason for hiding this comment

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

You're creating a new local variable here, so the outer socket remains null. Perhaps name this secureSocket, and then set socket = secureSocket after the "h2" if check below?

Choose a reason for hiding this comment

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

(also, is there any way to test this code path?)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oops
Thanks for catching this!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I added a simple round trip test.

The interop tests would also have caught this. They run on master.
They should be set up to run on travis for pull requests. I have got some hints how to do this, but never got around to it :(.

Copy link
Contributor

@domesticmouse domesticmouse left a comment

Choose a reason for hiding this comment

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

Lgtm

socket.done.then((_) => _abandonConnection());

// Give the settings settings-frame a bit of time to arrive.
await new Future.delayed(_estimatedRoundTripTime);

Choose a reason for hiding this comment

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

This seems like a smell - can we not be notified somehow when we're ready?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is indeed a hack.
I don't think the http2 package currently exposes the possibility of waiting for the settings frame. Not sure we are even guaranteed to have one.
I'll add a TODO reminding us of the smell.
@mkustermann might have more insight.

Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe add a comment that explains why we do this, and how it could be better.

final bool shouldRefresh =
_connectionLifeTimer.elapsed > options.connectionTimeout;
if (!isHealthy || shouldRefresh) {
if (isHealthy) {

Choose a reason for hiding this comment

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

This is the same as if (shouldRefresh), and there's no reason for it to be in the outer if block.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

True - that reads simpler.
Thanks!

@tvolkert
Copy link

The old appengine code used a Dialer to ensure only one new http/2 connection is made if multiple event loops try to establish a new connection. Does this handle that case?

pubspec.yaml Outdated
@@ -1,7 +1,7 @@
name: grpc
description: Dart implementation of gRPC, a high performance, open-source universal RPC framework.

version: 2.0.3
version: 2.0.4
Copy link
Contributor

Choose a reason for hiding this comment

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

Considering the new options added to the public API, it might be fine to do a minor version bump.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Right!
Done!

socket.done.then((_) => _abandonConnection());

// Give the settings settings-frame a bit of time to arrive.
await new Future.delayed(_estimatedRoundTripTime);
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe add a comment that explains why we do this, and how it could be better.

Copy link
Contributor Author

@sigurdm sigurdm left a comment

Choose a reason for hiding this comment

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

Thanks for the reviews!

socket.done.then((_) => _abandonConnection());

// Give the settings settings-frame a bit of time to arrive.
await new Future.delayed(_estimatedRoundTripTime);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is indeed a hack.
I don't think the http2 package currently exposes the possibility of waiting for the settings frame. Not sure we are even guaranteed to have one.
I'll add a TODO reminding us of the smell.
@mkustermann might have more insight.

final bool shouldRefresh =
_connectionLifeTimer.elapsed > options.connectionTimeout;
if (!isHealthy || shouldRefresh) {
if (isHealthy) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

True - that reads simpler.
Thanks!

if (securityContext == null) {
socket = await Socket.connect(host, port);
} else {
final socket = await SecureSocket.connect(host, port,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I added a simple round trip test.

The interop tests would also have caught this. They run on master.
They should be set up to run on travis for pull requests. I have got some hints how to do this, but never got around to it :(.

pubspec.yaml Outdated
@@ -1,7 +1,7 @@
name: grpc
description: Dart implementation of gRPC, a high performance, open-source universal RPC framework.

version: 2.0.3
version: 2.0.4
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Right!
Done!

@sigurdm sigurdm merged commit 992e2dc into grpc:master Aug 19, 2019
@tvolkert
Copy link

Thanks @sigurdm - can you publish this to Pub too?

@sigurdm
Copy link
Contributor Author

sigurdm commented Aug 20, 2019

Yep - done

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants