encode / broadcaster

Broadcast channels for async web apps. 📢
BSD 3-Clause "New" or "Revised" License
1.13k stars 121 forks source link

Test hangs with Redis backend in Starlette/FastAPI #44

Closed Buuntu closed 7 months ago

Buuntu commented 3 years ago

Using the testing example from the Starlette docs with a route that uses a Redis websocket just hangs indefinitely:

def test_websocket(client):
        with client.websocket_connect("/ws") as websocket:
            websocket.send_text("Hello WebSocket")
            data = websocket.receive_text()
            assert data == "Hello WebSocket"

this however, works fine:

def test_websocket(client):
        with client.websocket_connect("/ws") as websocket:
            assert True

maybe it's related to this https://github.com/encode/broadcaster/pull/2#issuecomment-591407905 and https://github.com/encode/broadcaster/issues/42?

I think it's the same with a memory backend. Has anyone successfully tested a Starlette websocket route?

UPDATE: I tried running ./scripts/test locally from the broadcaster directory and it actually hangs for me on the redis test. Anyone else getting that?

justinepdevasia commented 3 years ago

@Buuntu I too have got the same issue on testing ./scripts/test for redis. on examining with redis-cli monitor command inside redis, it is seen that publishing to the channel happens before subscribe and it is waiting forever to get published data.The test examined is

@pytest.mark.asyncio
async def test_redis():
    async with Broadcast("redis://localhost:6379") as broadcast:
        async with broadcast.subscribe("chatroom") as subscriber:
            await broadcast.publish("chatroom", "hello")
            event = await subscriber.get()
            assert event.channel == "chatroom"
            assert event.message == "hello"

Redis cli output

Screenshot 2021-11-01 at 3 23 28 PM

But it was working after adding a minimal delay before publish

import asyncio

@pytest.mark.asyncio
async def test_redis():
    async with Broadcast("redis://localhost:6379") as broadcast:
        async with broadcast.subscribe("chatroom") as subscriber:
            await asyncio.sleep(0.01)
            await broadcast.publish("chatroom", "hello")
            event = await subscriber.get()
            assert event.channel == "chatroom"
            assert event.message == "hello"

Redis cli output

Screenshot 2021-11-01 at 3 28 28 PM

In this case subscribe occur before publish and the test got passed. (looks like a Heisunbug)

alex-oleshkevich commented 8 months ago

We changed the underlying Redis library to redis-py. Can you please re-test if the issue is still there?

alex-oleshkevich commented 7 months ago

It does not hang either in tests nor in the example. I think this issue is fixed. Feel free to reopen.

alex-oleshkevich commented 7 months ago

Closing it as stalled. Feel free to reopen.