From 0413c152d8f21b90bc57f39a5d3f871a9a10e158 Mon Sep 17 00:00:00 2001 From: Jia Hao Date: Tue, 9 Jun 2020 00:04:20 +0800 Subject: [PATCH] Fix `Peer` requests not terminating when the channel closes (dart-lang/json_rpc_2#52) The `listen()` method of `Peer` never propagates close events from its manager to the `client` field. This causes in-flight requests to never terminate as the clean up handler in `client.dart` is never called. --- pkgs/json_rpc_2/CHANGELOG.md | 2 ++ pkgs/json_rpc_2/lib/src/peer.dart | 2 +- pkgs/json_rpc_2/test/peer_test.dart | 16 ++++++++++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/pkgs/json_rpc_2/CHANGELOG.md b/pkgs/json_rpc_2/CHANGELOG.md index 11e0cc269..9e5672376 100644 --- a/pkgs/json_rpc_2/CHANGELOG.md +++ b/pkgs/json_rpc_2/CHANGELOG.md @@ -1,5 +1,7 @@ ## 2.2.1-dev +* Fix `Peer` requests not terminating when the underlying channel is closed. + ## 2.2.0 * Added `strictProtocolChecks` named parameter to `Server` and `Peer` diff --git a/pkgs/json_rpc_2/lib/src/peer.dart b/pkgs/json_rpc_2/lib/src/peer.dart index eeb7cd9a6..7f89dd2cb 100644 --- a/pkgs/json_rpc_2/lib/src/peer.dart +++ b/pkgs/json_rpc_2/lib/src/peer.dart @@ -142,7 +142,7 @@ class Peer implements Client, Server { // server since it knows how to send error responses. _serverIncomingForwarder.add(message); } - }); + }).whenComplete(close); } @override diff --git a/pkgs/json_rpc_2/test/peer_test.dart b/pkgs/json_rpc_2/test/peer_test.dart index 33184b0ab..a9c295a0f 100644 --- a/pkgs/json_rpc_2/test/peer_test.dart +++ b/pkgs/json_rpc_2/test/peer_test.dart @@ -5,6 +5,7 @@ import 'dart:async'; import 'dart:convert'; +import 'package:pedantic/pedantic.dart'; import 'package:stream_channel/stream_channel.dart'; import 'package:test/test.dart'; @@ -84,6 +85,21 @@ void main() { expect(peer.sendRequest('w', {'x': 'y'}), completion(equals('z'))); }); }); + + test('requests terminates when the channel is closed', () async { + var incomingController = StreamController(); + var channel = StreamChannel.withGuarantees( + incomingController.stream, + StreamController(), + ); + var peer = json_rpc.Peer.withoutJson(channel); + unawaited(peer.listen()); + + var response = peer.sendRequest('foo'); + await incomingController.close(); + + expect(response, throwsStateError); + }); }); group('like a server,', () {