fix: keep alive timeout finishes transport instead of connection shutdown (#722)

* fix: keep alive timeout finishes transport instead of shutting down channel

* Update keepalive_test.dart

* Update CHANGELOG.md

---------

Co-authored-by: Moritz <mosum@google.com>
This commit is contained in:
steffenhaak 2024-09-06 17:13:11 +02:00 committed by GitHub
parent 81776333d9
commit 071ebc5f31
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 20 additions and 11 deletions

View File

@ -2,6 +2,8 @@
* Internal optimization to client code.
* Small fixes, such as ports in testing and enabling `timeline_test.dart`.
* When the keep alive manager runs into a timeout, it will finish the transport instead of closing
the connection, as defined in the gRPC spec.
## 4.0.1

View File

@ -113,7 +113,7 @@ class Http2ClientConnection implements connection.ClientConnection {
transport.ping();
}
},
onPingTimeout: () => shutdown(),
onPingTimeout: () => transport.finish(),
);
transport.onFrameReceived
.listen((_) => keepAliveManager?.onFrameReceived());

View File

@ -32,7 +32,7 @@ void main() {
late EchoServiceClient fakeClient;
late FakeClientChannel fakeChannel;
late EchoServiceClient unresponsiveClient;
late ClientChannel unresponsiveChannel;
late FakeClientChannel unresponsiveChannel;
final pingInterval = Duration(milliseconds: 10);
final timeout = Duration(milliseconds: 30);
@ -101,14 +101,18 @@ void main() {
expect(fakeChannel.newConnectionCounter, 1);
});
test('Server doesnt ack the ping, making the client shutdown the connection',
test('Server doesnt ack the ping, making the client shutdown the transport',
() async {
//Send a first request, get a connection
await unresponsiveClient.echo(EchoRequest());
expect(unresponsiveChannel.newConnectionCounter, 1);
//Ping is not being acked on time
await Future.delayed(timeout * 2);
await expectLater(
unresponsiveClient.echo(EchoRequest()),
throwsA(isA<GrpcError>()),
);
//A second request gets a new connection
await unresponsiveClient.echo(EchoRequest());
expect(unresponsiveChannel.newConnectionCounter, 2);
});
}
@ -146,7 +150,7 @@ class FakeHttp2ClientConnection extends Http2ClientConnection {
}
/// A wrapper around a [FakeHttp2ClientConnection]
class UnresponsiveClientChannel extends ClientChannel {
class UnresponsiveClientChannel extends FakeClientChannel {
UnresponsiveClientChannel(
super.host, {
super.port,
@ -155,11 +159,14 @@ class UnresponsiveClientChannel extends ClientChannel {
});
@override
ClientConnection createConnection() =>
ClientConnection createConnection() {
fakeHttp2ClientConnection =
UnresponsiveHttp2ClientConnection(host, port, options);
return fakeHttp2ClientConnection!;
}
}
class UnresponsiveHttp2ClientConnection extends Http2ClientConnection {
class UnresponsiveHttp2ClientConnection extends FakeHttp2ClientConnection {
UnresponsiveHttp2ClientConnection(super.host, super.port, super.options);
@override