strawberry-graphql / strawberry

A GraphQL library for Python that leverages type annotations 🍓
https://strawberry.rocks
MIT License
3.92k stars 516 forks source link

`connection_init_timeout` - "task destroyed but it is pending!" #2460

Open nrbnlulu opened 1 year ago

nrbnlulu commented 1 year ago

Describe the Bug

If a gql_transport_ws connection ended before connection_init_timeout asncio will warn: (if there were no event loops after the task was closed)

Task was destroyed but it is pending!
task: <Task pending name='Task-5' coro=<BaseGraphQLTransportWSHandler.handle_connection_init_timeout() running at /home/nir/Desktop/opensource/forks/strawberry/strawberry/subscriptions/protocols/graphql_transport_ws/handlers.py:75> wait_for=<Future pending cb=[Task.task_wakeup()]>>

Very annoying for tests.
repro:

async def test_connection_init_timeout():
    client = WebsocketCommunicator(
        GraphQLWSConsumer.as_asgi(
            schema=schema,
            # uncomment this and no warning will occure
            # connection_init_wait_timeout=timedelta(seconds=0),
            subscription_protocols=(GRAPHQL_TRANSPORT_WS_PROTOCOL,),
        ),
        "/graphql",
        subprotocols=[
            GRAPHQL_TRANSPORT_WS_PROTOCOL,
        ],
    )
    await asyncio.sleep(0.1)
    # Hope that the connection init timeout expired
    res = await client.connect()
    assert res == (True, GRAPHQL_TRANSPORT_WS_PROTOCOL)

    data = await client.receive_output()
    assert data["type"] == "websocket.close"
    assert data["code"] == 4408

System Information

Upvote & Fund

Fund with Polar

tsmith023 commented 1 year ago

@DoctorJohn, I'll have a look at this in the next few days :)

nrbnlulu commented 1 year ago

This might have been resolved by #2600

tsmith023 commented 1 year ago

I'm still seeing it in the testing logs:

Task was destroyed but it is pending!
task: <Task pending name='Task-615' coro=<BaseGraphQLTransportWSHandler.handle_connection_init_timeout() running at /home/tommy/Desktop/strawberry/strawberry/subscriptions/protocols/graphql_transport_ws/handlers.py:82> wait_for=<Future pending cb=[Task.task_wakeup()]>>

but it only throws once at the end of the entire suite. I'll dig into it!

rossmeredith commented 6 months ago

This still seems to be a problem which means websockets can't be tested. This is the simple test I have where I'm encountering this error.

@pytest.mark.asyncio
@pytest.mark.django_db
async def test_subscription():

    from strawberry.channels import GraphQLWSConsumer
    from api.schema import schema

    gql_ws_consumer = GraphQLWSConsumer.as_asgi(
        schema=schema,
        subscription_protocols=(GRAPHQL_TRANSPORT_WS_PROTOCOL,),
    )

    ws_communicator = WebsocketCommunicator(gql_ws_consumer, "/api/graphql")

    connected, subprotocol = await ws_communicator.connect()
    assert connected

Can this have a higher priority please since it's been so long since the last comment.