From 594044362be140e9ee5a016c7566af2cfdb6fe6f Mon Sep 17 00:00:00 2001 From: Agufa Tech Date: Wed, 6 Nov 2024 03:33:10 -0500 Subject: [PATCH 1/3] build(gql_websocket_link): upgrade web_socket_channel to v3.0.1, rxdart to >=0.26.0 <= 0.28.0 --- links/gql_websocket_link/pubspec.yaml | 4 ++-- .../test/gql_websocket_link_test.dart | 10 ++++++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/links/gql_websocket_link/pubspec.yaml b/links/gql_websocket_link/pubspec.yaml index 362bbb30a..99bfe6357 100644 --- a/links/gql_websocket_link/pubspec.yaml +++ b/links/gql_websocket_link/pubspec.yaml @@ -9,9 +9,9 @@ dependencies: gql_exec: ^1.0.0 gql_link: ^1.0.0 meta: ^1.3.0 - rxdart: '>=0.26.0 <0.28.0' + rxdart: '>=0.26.0 <=0.28.0' uuid: '>=3.0.0 <5.0.0' - web_socket_channel: ^2.0.0 + web_socket_channel: ^3.0.1 dev_dependencies: gql_pedantic: ^1.0.2 mockito: ^5.0.0 diff --git a/links/gql_websocket_link/test/gql_websocket_link_test.dart b/links/gql_websocket_link/test/gql_websocket_link_test.dart index d19aba707..ee7cfaae8 100644 --- a/links/gql_websocket_link/test/gql_websocket_link_test.dart +++ b/links/gql_websocket_link/test/gql_websocket_link_test.dart @@ -971,7 +971,6 @@ void _testLinks( link.request(request).listen( expectAsync1( (response) { - print(response); expect( response.data, responseData1, @@ -1239,9 +1238,16 @@ void _testLinks( server.transform(WebSocketTransformer()); webSocket = await WebSocket.connect("ws://localhost:${server.port}"); + channel = IOWebSocketChannel(webSocket); + channel.stream.asBroadcastStream().listen( + null, + onError: (Object err) { + print(err); + }, + onDone: () => print("done"), + ); // Close the socket to cause network error. await webSocket.close(); - channel = IOWebSocketChannel(webSocket); link = makeLink(null, channelGenerator: () => channel); expect( link.request(request).first, From 5e4309f3eb72e0faf18881b462d67e381187f302 Mon Sep 17 00:00:00 2001 From: Agufa Tech Date: Wed, 6 Nov 2024 04:11:34 -0500 Subject: [PATCH 2/3] test(gql_websocket_link): fix auto connect test --- .../test/gql_websocket_link_test.dart | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/links/gql_websocket_link/test/gql_websocket_link_test.dart b/links/gql_websocket_link/test/gql_websocket_link_test.dart index ee7cfaae8..5869ae0d9 100644 --- a/links/gql_websocket_link/test/gql_websocket_link_test.dart +++ b/links/gql_websocket_link/test/gql_websocket_link_test.dart @@ -1472,7 +1472,15 @@ void _testLinks( ), ); + final completer = Completer(); + final timer = Timer(const Duration(seconds: 5), () { + if (!completer.isCompleted) { + completer.completeError("Timeout"); + } + }); + server = await HttpServer.bind("localhost", 0); + var connectCount = 0; server.transform(WebSocketTransformer()).take(2).listen( expectAsync1( (webSocket) async { @@ -1491,6 +1499,10 @@ void _testLinks( ), ); webSocket.close(websocket_status.goingAway); + connectCount++; + if (connectCount == 2) { + completer.complete(); + } } messageCount++; }, @@ -1515,6 +1527,8 @@ void _testLinks( ); // link.request(request).listen(print, onError: print); + await completer.future; + timer.cancel(); }, ); From b199d03686cddfea939d5ab869cd72af91df0063 Mon Sep 17 00:00:00 2001 From: Agufa Tech Date: Thu, 7 Nov 2024 19:25:41 -0500 Subject: [PATCH 3/3] test(gql_websocket_link): fix auto reconnect test --- .../lib/src/graphql_transport_ws.dart | 32 ++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/links/gql_websocket_link/lib/src/graphql_transport_ws.dart b/links/gql_websocket_link/lib/src/graphql_transport_ws.dart index cf7025096..dab9253c8 100644 --- a/links/gql_websocket_link/lib/src/graphql_transport_ws.dart +++ b/links/gql_websocket_link/lib/src/graphql_transport_ws.dart @@ -551,10 +551,12 @@ class TransportWsClientOptions { class _Connected { final WebSocketChannel socket; final Future throwOnClose; + final Future likeCloseEvent; _Connected( this.socket, this.throwOnClose, + this.likeCloseEvent, ); } @@ -879,9 +881,26 @@ class _ConnectionState { retries = 0; // reset the retries on connect final _completer = Completer(); errorOrClosed(_completer.completeError); + // workground for dart linux bug: complete error not being caught by try..catch block + final _likeCloseEventCompleter = Completer(); connected(_Connected( socket, - _completer.future, + _completer.future.catchError((err) { + // workground for dart linux bug: complete error not being caught by try..catch block + // if the connection is closed, the error is not fatal + if (err is LikeCloseEvent) { + if (!_likeCloseEventCompleter.isCompleted) { + _likeCloseEventCompleter.complete(err); + } + return; + } + throw err; + }).whenComplete(() { + if (!_likeCloseEventCompleter.isCompleted) { + _likeCloseEventCompleter.complete(null); + } + }), + _likeCloseEventCompleter.future, )); } catch (err) { // stop reading messages as soon as reading breaks once @@ -930,6 +949,7 @@ class _ConnectionState { final socket = _connection.socket; final throwOnClose = _connection.throwOnClose; + final likeCloseEvent = _connection.likeCloseEvent; // if the provided socket is in a closing state, wait for the throw on close // TODO: WebSocketChannel should have a `state` getter @@ -972,6 +992,7 @@ class _ConnectionState { // or throwOnClose, ]), + waitForLikeCloseEvent: likeCloseEvent, ); } } @@ -1013,6 +1034,7 @@ class _Client extends TransportWsClient { final socket = _c.socket; final release = _c.release; final waitForReleaseOrThrowOnClose = _c.waitForReleaseOrThrowOnClose; + final waitForLikeCloseEvent = _c.waitForLikeCloseEvent; // print("isolate debug name: ${Isolate.current.debugName}"); // print(payload.operation.toString()); // print(payload.variables.toString()); @@ -1072,6 +1094,12 @@ class _Client extends TransportWsClient { // whatever happens though, we want to stop listening for messages await waitForReleaseOrThrowOnClose.whenComplete(unlisten); + // workground for dart linux bug: complete error not being caught by try..catch block + final likeCloseEvent = await waitForLikeCloseEvent; + if (likeCloseEvent != null) { + throw likeCloseEvent; + } + return; // completed, shouldnt try again } catch (errOrCloseEvent) { if (!state.shouldRetryConnectOrThrow(errOrCloseEvent)) return; @@ -1123,11 +1151,13 @@ class _Connection { final WebSocketChannel socket; final Completer release; final Future waitForReleaseOrThrowOnClose; + final Future waitForLikeCloseEvent; _Connection({ required this.socket, required this.release, required this.waitForReleaseOrThrowOnClose, + required this.waitForLikeCloseEvent, }); }