Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Daphne 3.0 problem with request-response when working with Channels #345

Closed
Ivo-Donchev opened this issue Nov 12, 2020 · 7 comments
Closed

Comments

@Ivo-Donchev
Copy link

Ivo-Donchev commented Nov 12, 2020

Hi,

I'm facing a strange issue with Daphne 3 + Channels 3.0.2 and handling multiple request.
I setup a really simple project so we have a base for discussion :)
So, I'm running the project on OS Ubuntu 18.04 with python 3.7.
My requirements are:

Django==3.1.3
daphne==3.0.0
channels==3.0.2
django-environ==0.4.5

My setup

  1. I registered channels in installed apps and pointed to this routing:
application = ProtocolTypeRouter({
    'websocket': URLRouter([])
})

  1. I added 2 simple views:
def view_1(request):  # Url is `/1/`
    make_it_slow()  # Sleeps for 3 seconds
    return HttpResponse('view_1 response')


def view_2(request):  # Url is `/2/`
    make_it_slow()  # Sleeps for 3 seconds
    return HttpResponse('view_2 response')
  1. I ran the application:
daphne daphne_3_issue_demo.asgi:application

The issue

So I opened 2 shells and ran these in parralel:
curl http://localhost:8000/1/ and curl http://localhost:8000/2/

So what I noticed is that the first finished response arrives to the last requesting client and the other request just hangs until it times out.

Here's what I mean:
daphne_issue

P.S.: I think this issue is extending the existing one but it's not the exactly the same.

Best regards,
Ivo

@carltongibson
Copy link
Member

Hi @Ivo-Donchev — thanks for the report — sample project, top marks 🥇 😀

I'll need to have a play, but first thing to note it that you're not using your routing.py at all — you define the app there but then run the app from asgi.py. So I'm not sure Channels is involved at all 🤔

@carltongibson
Copy link
Member

Hmmm. 🤔 Downloading your project, creating a fresh venv, and setting up the same, I'm not seeing the issue — I'm getting the two curl sessions operating as expected.

@Ivo-Donchev
Copy link
Author

Hi @carltongibson
Thanks for the quick response 🙇 I deleted the the consumer on purpose and the issue still persisted.
However I just tested it again and the issue was definetely there when running with python manage.py runserver but with daphne daphne_3_issue_demo.asgi:application it was okay o_O (I have nightmares with such random issues ... 🙄 😄 ).

I've deleted all my __pycache__ or pyc files and it's not that. Maybe I'm missing something 🤔 Will play with it today trying to isolate it and make it not random and will write back here to not lose your time too since I'm now not 100% sure it's a Daphne issue. 🙂

@carltongibson
Copy link
Member

OK, super. Once you have it isolated, do come back. Thanks

@Ivo-Donchev
Copy link
Author

@carltongibson I found the problem. It's not Daphne

The problem was:
Our production project was (and still is) using django 2.2 with channels 2.x and daphne 2.x. Channels 2.x used to allow not specifying the http application inside the ProtocolTypeRouter, where channels 3.x seems change the behaviour and if you directly update the dependencies and skip reading the new docs (like I did) it started producing this weird bug with the parallel requests.

So to solve this I just put both http and websocket protocols at one place inside ProtocolTypeRouter. I guess it'll be a good idea if it had some warning.. but that's definetely not a Daphne problem . Sorry for the fake alarm and thanks for the quick response again 🙂

P.S: That could actually be a fix for the other issue mentioned above - #344 🤔

@carltongibson
Copy link
Member

Hey @Ivo-Donchev. Thanks for the confirmation.

...good idea if it had some warning...

Yes, I couldn't find a good way to add that in the time I had available. Ultimately it's a major change all throughout, so it wasn't exactly clear what to put where to let people know they'd missed updating. Not providing the http key to ProtocolTypeRouter should raise a warning though.

@Ivo-Donchev
Copy link
Author

Ivo-Donchev commented Nov 12, 2020

@carltongibson I actually jumped in channels' the code a little bit to checkout for a good place to put such warning and it turned out there's one - https://github.com/django/channels/blob/master/channels/routing.py#L63 👍 . However it wasn't shown in the server logs - neither runserver nor daphne. Maybe it needs some additional logging configuration than the default one.

Thinking out loud: I think it's Django job to make sure the application instance (no matter it's channels or something else) is done just once probably even in the View and Consumer implementations since since they're always the very last end points for all routes. That could handle most of the cases: someone using Django as pure http server or pure websocket server (which will raise a warning at the moment) + someone trying to handle any of http/websocket protocols at 2 places. Also - it'll handle both runserver and daphne or other production application server. But I'm not into the very details of the server handling implementation, just throwing some "make sense to me" ideas here 🙂

jclgoodwin added a commit to jclgoodwin/bustimes.org that referenced this issue Dec 12, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants