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

Make StrawberryShake's subscription can finish automatically.

Open CoreDX9 opened this issue 2 years ago • 7 comments

I think OnCompleted callback of console client will be triggered if add observer.OnCompleted(); before session.RequestSession.Dispose();. https://github.com/ChilliCream/hotchocolate/blob/b56f0e96487fa7b2d4423d1cf1310b33aea73250/src/StrawberryShake/Client/src/Core/OperationExecutor.Observable.cs#L132-L134

In Microsoft Docs: IObservable{T} Interface

   public void EndTransmission()
   {
      foreach (var observer in observers.ToArray())
         if (observers.Contains(observer))
            observer.OnCompleted();

      observers.Clear();
   }

IObservable should call observer's OnCompleted method to notify observer there is no further data is available.

Originally posted by @CoreDX9 in https://github.com/ChilliCream/hotchocolate/issues/4813#issuecomment-1106632461

CoreDX9 avatar Apr 26 '22 07:04 CoreDX9

If convert IObservable{T} to AsyncEnumerable and use await foreach to enumerate stream, but observers never call OnCompleted, the thread will be permanently blocked.

CoreDX9 avatar Apr 26 '22 07:04 CoreDX9

If web socket client closed because of network error, session don't notify subscription. GraphQLWebSocketProtocol need operation id to trigger Notify method. So I use reflection to access nonpublic fields to complete subscription stream.

There is my solution. Can you add to StrawberryShake? This may require modifying the interface definition.

https://github.com/CoreDX9/GraphqlSubscriptionTest/blob/0ae3c6a651bf80b43d05b97a16cead6bce3f5f44/Libs/Core/OperationExecutor.Observable.cs#L133

https://github.com/CoreDX9/GraphqlSubscriptionTest/blob/0ae3c6a651bf80b43d05b97a16cead6bce3f5f44/TestClient/Program.cs#L89-L173

CoreDX9 avatar Apr 26 '22 08:04 CoreDX9

@CoreDX9 You seem to know your way around web sockets do you think https://github.com/ChilliCream/hotchocolate/issues/4824 could be caused by what you are describing here? No need to for definite yes or no just best guess is enough. My subscriptions tests are flaky when running in CI and I can imagine not releasing threads on resource limited machine could be the reason why. Its hard to test because its like one in 20 whole test suite runs either way I guess I will find out when your PR gets released:)

kolpav avatar May 03 '22 10:05 kolpav

@kolpav I don't think so. Subscriptions use Task to process network stream, The Watch method will return when the task is created successfully. But the network connection may not be ready. Therefore, you can only try to check whether the subscription is working. If you want the test to be more reliable, you can only increase the number of retries and delay time.

CoreDX9 avatar May 05 '22 17:05 CoreDX9

@kolpav If the network connection fails,OnError callback will be triggered. If the server actively ends the subscription, OnComplete callback will be triggered when the pull request #5008 merged into main branch. If the network connection is successful, then the connection is accidentally disconnected. See also my interim solution.

CoreDX9 avatar May 05 '22 17:05 CoreDX9

@CoreDX9 I am now thinking about creating repro repo with CI, thank you for explanation 👍

kolpav avatar May 05 '22 20:05 kolpav

Stale issue message

github-actions[bot] avatar Jul 04 '22 20:07 github-actions[bot]