-
Notifications
You must be signed in to change notification settings - Fork 139
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
Move to ASGI using Daphne #2941
Comments
For reference, the # asgi.py
"""
ASGI config for test_django_project project.
It exposes the ASGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/4.2/howto/deployment/asgi/
"""
import os
from django.core.asgi import get_asgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'test_django_project.settings')
application = get_asgi_application() |
Poetry installbuildvm:/opt/rockstor # poetry add -vv daphne
Using virtualenv: /opt/rockstor/.venv
Using version ^4.1.2 for daphne
Updating dependencies
Resolving dependencies...
(...)
1: derived: daphne (>=4.1.2,<5.0.0)
(...)
1: fact: daphne (4.1.2) depends on asgiref (>=3.5.2,<4)
1: fact: daphne (4.1.2) depends on autobahn (>=22.4.2)
1: fact: daphne (4.1.2) depends on twisted (>=22.4)
1: selecting daphne (4.1.2)
(...)
1: Version solving took 0.292 seconds.
1: Tried 1 solutions.
Finding the necessary packages for the current system
Package operations: 13 installs, 0 updates, 0 removals, 52 skipped
• Installing pyasn1 (0.6.1)
• Installing attrs (24.3.0)
• Installing pyasn1-modules (0.4.1)
• Installing automat (24.8.1)
• Installing constantly (23.10.4)
• Installing hyperlink (21.0.0)
• Installing incremental (24.7.2)
• Installing pyopenssl (24.3.0)
• Installing service-identity (24.2.0)
• Installing txaio (23.1.1)
• Installing autobahn (24.4.2)
• Installing twisted (24.11.0)
• Installing daphne (4.1.2)
Writing lock file buildvm:/opt/rockstor # poetry show daphne --tree
daphne 4.1.2 Django ASGI (HTTP/WebSocket) server
├── asgiref >=3.5.2,<4
├── autobahn >=22.4.2
│ ├── cryptography >=3.4.6
│ │ └── cffi >=1.12
│ │ └── pycparser *
│ ├── hyperlink >=21.0.0
│ │ └── idna >=2.5
│ ├── setuptools *
│ └── txaio >=21.2.1
└── twisted >=22.4
├── attrs >=22.2.0
├── automat >=24.8.0
├── constantly >=15.1
├── hyperlink >=17.1.1
│ └── idna >=2.5
├── idna >=2.4 (circular dependency aborted here)
├── incremental >=24.7.0
│ └── setuptools >=61.0
├── pyopenssl >=21.0.0
│ └── cryptography >=41.0.5,<45
│ └── cffi >=1.12
│ └── pycparser *
├── service-identity >=18.1.0
│ ├── attrs >=19.1.0 (circular dependency aborted here)
│ ├── cryptography * (circular dependency aborted here)
│ ├── pyasn1 *
│ └── pyasn1-modules *
│ └── pyasn1 >=0.4.6,<0.7.0 (circular dependency aborted here)
├── typing-extensions >=4.2.0
└── zope-interface >=5
└── setuptools * (circular dependency aborted here) Daphne commandThe install results in a binary available in our Poetry env: buildvm:/opt/rockstor # poetry run daphne --help
usage: daphne [-h] [-p PORT] [-b HOST] [--websocket_timeout WEBSOCKET_TIMEOUT] [--websocket_connect_timeout WEBSOCKET_CONNECT_TIMEOUT] [-u UNIX_SOCKET] [--fd FILE_DESCRIPTOR] [-e SOCKET_STRINGS] [-v VERBOSITY] [-t HTTP_TIMEOUT] [--access-log ACCESS_LOG]
[--log-fmt LOG_FMT] [--ping-interval PING_INTERVAL] [--ping-timeout PING_TIMEOUT] [--application-close-timeout APPLICATION_CLOSE_TIMEOUT] [--root-path ROOT_PATH] [--proxy-headers] [--proxy-headers-host PROXY_HEADERS_HOST]
[--proxy-headers-port PROXY_HEADERS_PORT] [-s SERVER_NAME] [--no-server-name]
application
Django HTTP/WebSocket server
positional arguments:
application The application to dispatch to as path.to.module:instance.path
options:
-h, --help show this help message and exit
-p PORT, --port PORT Port number to listen on
-b HOST, --bind HOST The host/address to bind to
--websocket_timeout WEBSOCKET_TIMEOUT
Maximum time to allow a websocket to be connected. -1 for infinite.
--websocket_connect_timeout WEBSOCKET_CONNECT_TIMEOUT
Maximum time to allow a connection to handshake. -1 for infinite
-u UNIX_SOCKET, --unix-socket UNIX_SOCKET
Bind to a UNIX socket rather than a TCP host/port
--fd FILE_DESCRIPTOR Bind to a file descriptor rather than a TCP host/port or named unix socket
-e SOCKET_STRINGS, --endpoint SOCKET_STRINGS
Use raw server strings passed directly to twisted
-v VERBOSITY, --verbosity VERBOSITY
How verbose to make the output
-t HTTP_TIMEOUT, --http-timeout HTTP_TIMEOUT
How long to wait for worker before timing out HTTP connections
--access-log ACCESS_LOG
Where to write the access log (- for stdout, the default for verbosity=1)
--log-fmt LOG_FMT Log format to use
--ping-interval PING_INTERVAL
The number of seconds a WebSocket must be idle before a keepalive ping is sent
--ping-timeout PING_TIMEOUT
The number of seconds before a WebSocket is closed if no response to a keepalive ping
--application-close-timeout APPLICATION_CLOSE_TIMEOUT
The number of seconds an ASGI application has to exit after client disconnect before it is killed
--root-path ROOT_PATH
The setting for the ASGI root_path variable
--proxy-headers Enable parsing and using of X-Forwarded-For and X-Forwarded-Port headers and using that as the client address
--proxy-headers-host PROXY_HEADERS_HOST
Specify which header will be used for getting the host part. Can be omitted, requires --proxy-headers to be specified when passed. "X-Real-IP" (when passed by your webserver) is a good candidate for this.
--proxy-headers-port PROXY_HEADERS_PORT
Specify which header will be used for getting the port part. Can be omitted, requires --proxy-headers to be specified when passed.
-s SERVER_NAME, --server-name SERVER_NAME
specify which value should be passed to response header Server attribute
--no-server-name |
Very crude replacement of gunicorn in
Re-build, and we see in the daphne logs (interestingly seems to only write to stderr with these settings):
Open browser to webUI:
First thing we notice is that the daphne logs seem to duplicate rockstor.log to some extent.
Although the submission of the sign-up form itself goes well, nothing seems to happen past that. Looking at Firefox's developer tools, we can see that:
My best guess so far is something related to headers that is not properly transmitted. |
Daphne was originally developed for Django Channels, so we can find some additional documentation there. In particular, there is some guide on deploying using Daphne controlled by Supervisord behind Nginx: |
The answer seems to be in the headers, indeed. First, add the
The
Out of these 4, adding just one (
In the Daphne log, we now see all seems to be fine:
According to Mozilla's docs, this header does the following:
|
This represents a work in progress and not suitable for use yet. This commits includes first draft for minimum changes for Daphne to work and all unit tests to still pass.
Building upon the recent hard work moving us to modern Python and Django, we can now open new possibilities for Rockstor for more dynamic behaviors and overall better user experience. Some of these would rely on async code, however, which means we need to move to serving our Django app with a compatible server: one that supports ASGI.
Following Django's documentation (https://docs.djangoproject.com/en/4.2/howto/deployment/asgi/), we have several options:
Out of these, Daphne seems to be a preferred choice overall, as it has been created "by and for" Django (Django channels, I believe), and is currently actively maintained by Django:
https://github.com/django/daphne
https://docs.djangoproject.com/en/4.2/howto/deployment/asgi/daphne/
Note this might be preferred to be accomplished after #2650.
This move would also be a requirement for #2739.
The text was updated successfully, but these errors were encountered: