From cb998ea7522aa74051ea55e461183c2cf3a5eff3 Mon Sep 17 00:00:00 2001 From: James Pellow Date: Fri, 20 Sep 2024 15:57:38 -0700 Subject: [PATCH 1/2] Fix race causing double release in gql_websocket_link --- .../lib/src/graphql_transport_ws.dart | 14 +++++++++++++- 1 file changed, 13 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 dc72592a..228a1fd2 100644 --- a/links/gql_websocket_link/lib/src/graphql_transport_ws.dart +++ b/links/gql_websocket_link/lib/src/graphql_transport_ws.dart @@ -974,7 +974,12 @@ class _Client extends TransportWsClient { bool done = false; bool errored = false; + bool released = false; + Function() releaser = () { + if (released) return; + released = true; + // for handling completions before connect state.locks--; done = true; @@ -1018,8 +1023,15 @@ class _Client extends TransportWsClient { // if not completed already and socket is open, send complete message to server on release socket.sink.add(_completeMsg); } - state.locks--; + done = true; + + // Its possible for a CompleteMessage to be received during the await above + // and this code be run twice causing a double release issue. + if (released) return; + released = true; + + state.locks--; release(); }; From 49ed16c5cc17595c2ce898e6c9a9c961aa07286e Mon Sep 17 00:00:00 2001 From: James Pellow Date: Fri, 20 Sep 2024 15:59:29 -0700 Subject: [PATCH 2/2] Fix completer already completed error in gql_websocket_link --- links/gql_websocket_link/lib/src/graphql_transport_ws.dart | 7 ++++++- 1 file changed, 6 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 228a1fd2..8e5b0482 100644 --- a/links/gql_websocket_link/lib/src/graphql_transport_ws.dart +++ b/links/gql_websocket_link/lib/src/graphql_transport_ws.dart @@ -853,7 +853,12 @@ class _ConnectionState { retrying = false; // future lazy connects are not retries retries = 0; // reset the retries on connect final _completer = Completer(); - errorOrClosed(_completer.completeError); + + errorOrClosed((error) { + if (_completer.isCompleted) return; + _completer.completeError(error); + }); + connected(_Connected( socket, _completer.future,