graphql-client icon indicating copy to clipboard operation
graphql-client copied to clipboard

GraphQL Client is not able to reconnect if graphQL server restart

Open akoliya003 opened this issue 5 years ago • 9 comments
trafficstars

Hi,

GraphQL Client is not able to reconnect if graphQL server restart. In my local copy below is the change I have added.

GraphQL.Client --> Http --> GraphQLHttpWebSocket.cs --> _receiveResultAsync(...) --> 
			.....
                         catch (Exception e)
			{
				**await _closeAsync().ConfigureAwait(false);
				clientWebSocket?.Dispose();**
				Debug.WriteLine($"exception thrown while receiving websocket data: {e}");
				throw;
			}

You may also have some better way.

-----------------------------------------------------------------------------------------------
WebSocketException: The remote party closed the WebSocket connection without completing the close handshake. (WebSocketError ConnectionClosedPrematurely, ErrorCode 0, NativeErrorCode 0
WebSocketException: The remote party closed the WebSocket connection without completing the close handshake. (WebSocketError ConnectionClosedPrematurely, ErrorCode 0, NativeErrorCode 0
System.NullReferenceException: Object reference not set to an instance of an object.
   at GraphQL.Client.Http.Websocket.GraphQLHttpWebsocketHelpers.<>c__DisplayClass0_0`1.<CreateSubscriptionStream>b__3(Exception e)
System.Net.WebSockets.WebSocketException (0x80004005): The remote party closed the WebSocket connection without completing the close handshake. ---> System.IO.IOException: Unable to transfer data on the transport connection: Broken pipe. ---> System.Net.Sockets.SocketException: Broken pipe
   --- End of inner exception stack trace ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Net.WebSockets.ManagedWebSocket.<SendFrameFallbackAsync>d__56.MoveNext()
   at System.Net.WebSockets.ManagedWebSocket.<SendFrameFallbackAsync>d__56.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at GraphQL.Client.Http.Websocket.GraphQLHttpWebSocket.<_sendWebSocketRequest>d__24.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at GraphQL.Client.Http.Websocket.GraphQLHttpWebsocketHelpers.<>c__DisplayClass0_0`1.<<CreateSubscriptionStream>b__5>d.MoveNext()

akoliya003 avatar Mar 04 '20 16:03 akoliya003

I'm aware of an issue with the reconnect capability, seems there is a threading problem within the observable chain... Hopefully I'll be able to fix this in the coming days

rose-a avatar Mar 04 '20 19:03 rose-a

Hi Alexander,

Thanks for your prompt reply on this.

Appreciate your help.

Thanks, Bhavesh

On Wed, Mar 4, 2020 at 1:31 PM Alexander Rose [email protected] wrote:

I'm aware of an issue with the reconnect capability, seems there is a threading problem within the observable chain... Hopefully I'll be able to fix this in the coming days

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/graphql-dotnet/graphql-client/issues/180?email_source=notifications&email_token=AIYRHNCJDVHHSPYGHFZW7FDRF2UAHA5CNFSM4LBL7GB2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOENZZX6Y#issuecomment-594779131, or unsubscribe https://github.com/notifications/unsubscribe-auth/AIYRHNF2RVCNKZKRRS75FGDRF2UAHANCNFSM4LBL7GBQ .

akoliya003 avatar Mar 04 '20 19:03 akoliya003

The exception is as expected and you cannot call closeAsync() there because the websocket is in an aborted state. This is taken care of by InitializeWebSocket() which disposes the old websocket instance if it's in a bad state and creates a new one...

This should automatically happen through the Retry() method in the subscriptions observable chain.

Maybe you could configure a custom GraphQLHttpClientOptions.BackOffStrategy and check if this method is invoked after you shut down the server?

rose-a avatar Mar 04 '20 19:03 rose-a

Somehow this seems to be related with #161...

rose-a avatar Mar 04 '20 20:03 rose-a

I tried adding custom GraphQLHttpClientOptions.BackOffStrategy and checked that method is not invoked at all.

Instead of retries it raise below exception:

-------
WebSocketException: The remote party closed the WebSocket connection without completing the close handshake. (WebSocketError ConnectionClosedPrematurely, ErrorCode 0, NativeErrorCode 0
WebSocketException: The remote party closed the WebSocket connection without completing the close handshake. (WebSocketError ConnectionClosedPrematurely, ErrorCode 0, NativeErrorCode 0
System.NullReferenceException: Object reference not set to an instance of an object.
   at GraphQL.Client.Http.Websocket.GraphQLHttpWebsocketHelpers.<>c__DisplayClass0_0`1.<CreateSubscriptionStream>b__3(Exception e)
System.Net.WebSockets.WebSocketException (0x80004005): The remote party closed the WebSocket connection without completing the close handshake. ---> System.IO.IOException: Unable to transfer data on the transport connection: Broken pipe. ---> System.Net.Sockets.SocketException: Broken pipe
   --- End of inner exception stack trace ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Net.WebSockets.ManagedWebSocket.<SendFrameFallbackAsync>d__56.MoveNext()
   at System.Net.WebSockets.ManagedWebSocket.<SendFrameFallbackAsync>d__56.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at GraphQL.Client.Http.Websocket.GraphQLHttpWebSocket.<_sendWebSocketRequest>d__24.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at GraphQL.Client.Http.Websocket.GraphQLHttpWebsocketHelpers.<>c__DisplayClass0_0`1.<<CreateSubscriptionStream>b__5>d.MoveNext()
---------------

akoliya003 avatar Mar 04 '20 20:03 akoliya003

What i understood.

Once GraphQL server restarts, it disconnect the connection. At this point at client side _receiveResultAsync(...) method throw an exception and that exception all the way pass to application and no retry is called in this flow. As per me as soon we get exception in that method we should trigger retries and trigger invalidate existing socket so InitializeWebSocket(..) will take care on next read request.

If i start GraphQL client application first and then start the server then it works fine as graphQL client application keep trying to reconnect and finally connects with server once it is up and running.

I hope. This information will help.

On Wed, Mar 4, 2020 at 2:01 PM Alexander Rose [email protected] wrote:

Somehow this seems to be related with #161 https://github.com/graphql-dotnet/graphql-client/issues/161...

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/graphql-dotnet/graphql-client/issues/180?email_source=notifications&email_token=AIYRHNEDKUFLL3N2GPBYKD3RF2XQNA5CNFSM4LBL7GB2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOENZ7GEI#issuecomment-594801425, or unsubscribe https://github.com/notifications/unsubscribe-auth/AIYRHNDCAU7ZRML2YSZOTUDRF2XQNANCNFSM4LBL7GBQ .

akoliya003 avatar Mar 04 '20 20:03 akoliya003

that exception all the way pass to application

Where does that exception surface? Does it call OnError on your subscription?

rose-a avatar Mar 09 '20 09:03 rose-a

Yes,

Below is the Exception details:

----------------------
testGraphQL.WScoreUpdate
WebSocketException: The remote party closed the WebSocket connection without completing the close handshake. (WebSocketError ConnectionClosedPrematurely, ErrorCode 424189040, NativeErrorCode 424189040
WebSocketException: The remote party closed the WebSocket connection without completing the close handshake. (WebSocketError ConnectionClosedPrematurely, ErrorCode 0, NativeErrorCode 0
System.NullReferenceException: Object reference not set to an instance of an object.
   at GraphQL.Client.Http.Websocket.GraphQLHttpWebsocketHelpers.<>c__DisplayClass0_0`1.<CreateSubscriptionStream>b__3(Exception e)
System.Net.WebSockets.WebSocketException (0x80004005): The remote party closed the WebSocket connection without completing the close handshake. ---> System.IO.IOException: Unable to transfer data on the transport connection: Broken pipe. ---> System.Net.Sockets.SocketException: Broken pipe
   --- End of inner exception stack trace ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Net.WebSockets.ManagedWebSocket.<SendFrameFallbackAsync>d__56.MoveNext()
   at System.Net.WebSockets.ManagedWebSocket.<SendFrameFallbackAsync>d__56.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at GraphQL.Client.Http.Websocket.GraphQLHttpWebSocket.<_sendWebSocketRequest>d__24.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at GraphQL.Client.Http.Websocket.GraphQLHttpWebsocketHelpers.<>c__DisplayClass0_0`1.<<CreateSubscriptionStream>b__5>d.MoveNext()
----------

akoliya003 avatar Mar 11 '20 16:03 akoliya003

Did you pass a custom exception handler? This exception is normally swallowed by and causes a Retry on the subscription.

Please also update to the latest version of this lib, as I made some optimizations to the code behind...

rose-a avatar Mar 16 '20 10:03 rose-a