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

fix: fix headers not completing when call is terminated #728

Merged
merged 5 commits into from
Aug 28, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 4.0.1

* Fix header and trailing not completing if the call is terminated. Fixes [#727](https://github.com/grpc/grpc-dart/issues/727)

## 4.0.0

* Set compressed flag correctly for grpc-encoding = identity. Fixes [#669](https://github.com/grpc/grpc-dart/issues/669) (https://github.com/grpc/grpc-dart/pull/693)
Expand Down
6 changes: 6 additions & 0 deletions lib/src/client/call.dart
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,12 @@ class ClientCall<Q, R> implements Response {
if (_responseSubscription != null) {
futures.add(_responseSubscription!.cancel());
}
if (!_headers.isCompleted) {
_headers.complete({});
}
if (!_trailers.isCompleted) {
_trailers.complete({});
}
await Future.wait(futures);
}

Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: grpc
description: Dart implementation of gRPC, a high performance, open-source universal RPC framework.
version: 4.0.0
version: 4.0.1

repository: https://github.com/grpc/grpc-dart

Expand Down
69 changes: 69 additions & 0 deletions test/client_tests/call_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,26 @@
// See the License for the specific language governing permissions and
// limitations under the License.

import 'package:grpc/grpc.dart';
import 'package:grpc/src/client/call.dart';
import 'package:test/test.dart';

import '../src/client_utils.dart';

void main() {
const dummyValue = 0;
const cancelDurationMillis = 300;

late ClientHarness harness;

setUp(() {
harness = ClientHarness()..setUp();
});

tearDown(() {
harness.tearDown();
});

test('WebCallOptions mergeWith CallOptions returns WebCallOptions', () {
final options =
WebCallOptions(bypassCorsPreflight: true, withCredentials: true);
Expand All @@ -28,4 +44,57 @@ void main() {
expect(mergedOptions.bypassCorsPreflight, true);
expect(mergedOptions.withCredentials, true);
});

test(
'Cancelling a call correctly complete headers future',
() async {
final clientCall = harness.client.unary(dummyValue);

Future.delayed(
Duration(milliseconds: cancelDurationMillis),
).then((_) => clientCall.cancel());

expect(await clientCall.headers, isEmpty);

await expectLater(
clientCall,
throwsA(
isA<GrpcError>().having(
(e) => e.codeName,
'Test codename',
contains('CANCELLED'),
),
),
);
},
);

test(
'Cancelling a call correctly complete trailers futures',
() async {
final clientCall = harness.client.unary(dummyValue);

Future.delayed(
Duration(milliseconds: cancelDurationMillis),
).then((_) {
clientCall.cancel();
});

expect(
await clientCall.trailers,
isEmpty,
);

await expectLater(
clientCall,
throwsA(
isA<GrpcError>().having(
(e) => e.codeName,
'Test codename',
contains('CANCELLED'),
),
),
);
},
);
}
2 changes: 1 addition & 1 deletion test/keepalive_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ void main() {
services: [FakeEchoService()],
keepAliveOptions: serverOptions,
);
await server.serve(address: 'localhost', port: 8081);
await server.serve(address: 'localhost', port: 8082);
mosuem marked this conversation as resolved.
Show resolved Hide resolved
fakeChannel = FakeClientChannel(
'localhost',
port: server.port!,
Expand Down