ecthiender / py-graphql-client

Dead-simple GraphQL client with subscriptions over websockets
https://pypi.org/project/py-graphql-client/
Other
37 stars 11 forks source link

"cannot join current thread" when close() called on running client #35

Open kdowney-cloudwallcapital opened 2 years ago

kdowney-cloudwallcapital commented 2 years ago

On Python 3.8.12 with py-graphql-client 0.1.1 and websockets-client 0.54.0 running on Ubuntu focal, I see this exception when I call close():

stopping 5990f26aabc1472bad9913d8d3cf34b9
Exception in thread Thread-1:
Traceback (most recent call last):
  File "/usr/local/python/lib/python3.8/threading.py", line 932, in _bootstrap_inner
    self.run()
  File "/usr/local/python/lib/python3.8/threading.py", line 870, in run
    self._target(*self._args, **self._kwargs)
  File "/workspaces/serenity.core/venv/lib/python3.8/site-packages/graphql_client/__init__.py", line 118, in _receiver_task
    user_fn(op_id, msg)
  File "src/python/serenity/core/utils/rfb_check.py", line 17, in callback
    client.close()
  File "/workspaces/serenity.core/venv/lib/python3.8/site-packages/graphql_client/__init__.py", line 239, in close
    self._recevier_thread.join()
  File "/usr/local/python/lib/python3.8/threading.py", line 1008, in join
    raise RuntimeError("cannot join current thread")
RuntimeError: cannot join current thread

Example that reproduces the issue:

from time import sleep

from graphql_client import GraphQLClient

client = GraphQLClient('ws://localhost:9002/graphql/subscriptions')
sub_ids = []

def callback(_id, data):
    if data['type'] == 'complete':
        for sub_id in sub_ids:
            print(f'stopping {sub_id}')
            client.stop_subscribe(sub_id)
            client.close()
    else:
        print(f"msg id: {_id}. data: {data}")

query = """
subscription {
    overallPortfolioSummaries {
        weight
    }
}
"""

sub_ids.append(client.subscribe(query, callback=callback))
kdowney-cloudwallcapital commented 2 years ago

Note the workaround is pretty easy, even if it's a hack. Replace the close() with this:

            # bug in graphql_client; close() tries join() current thread
            client._shutdown_receiver = True
            client._connection.close()