mirror of
https://github.com/django/daphne.git
synced 2026-01-06 00:09:02 +03:00
Merge 888ada94fd into 8b5696768f
This commit is contained in:
commit
f3140c5448
|
|
@ -160,6 +160,12 @@ class CommandLineInterface:
|
|||
self.parser.add_argument(
|
||||
"--no-server-name", dest="server_name", action="store_const", const=""
|
||||
)
|
||||
self.parser.add_argument(
|
||||
"--enable-lifespan",
|
||||
dest="enable_lifespan",
|
||||
action="store_true",
|
||||
help="Enables lifespan support.",
|
||||
)
|
||||
|
||||
self.server = None
|
||||
|
||||
|
|
@ -279,6 +285,7 @@ class CommandLineInterface:
|
|||
action_logger=(
|
||||
AccessLogGenerator(access_log_stream) if access_log_stream else None
|
||||
),
|
||||
enable_lifespan=args.enable_lifespan,
|
||||
root_path=args.root_path,
|
||||
verbosity=args.verbosity,
|
||||
proxy_forwarded_address_header=self._get_forwarded_host(args=args),
|
||||
|
|
|
|||
|
|
@ -51,6 +51,13 @@ class Command(RunserverCommand):
|
|||
default=True,
|
||||
help="Run the old WSGI-based runserver rather than the ASGI-based one",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--enable-lifespan",
|
||||
action="store_true",
|
||||
dest="enable_lifespan",
|
||||
default=False,
|
||||
help="Enable lifespan support.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--http_timeout",
|
||||
action="store",
|
||||
|
|
@ -141,6 +148,7 @@ class Command(RunserverCommand):
|
|||
application=self.get_application(options),
|
||||
endpoints=endpoints,
|
||||
signal_handlers=not options["use_reloader"],
|
||||
enable_lifespan=options["enable_lifespan"],
|
||||
action_logger=self.log_action,
|
||||
http_timeout=self.http_timeout,
|
||||
root_path=getattr(settings, "FORCE_SCRIPT_NAME", "") or "",
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import sys # isort:skip
|
|||
import warnings # isort:skip
|
||||
from concurrent.futures import ThreadPoolExecutor # isort:skip
|
||||
from twisted.internet import asyncioreactor # isort:skip
|
||||
from monkay.asgi import Lifespan # isort:skip
|
||||
|
||||
|
||||
twisted_loop = asyncio.new_event_loop()
|
||||
|
|
@ -66,6 +67,7 @@ class Server:
|
|||
application_close_timeout=10,
|
||||
ready_callable=None,
|
||||
server_name="daphne",
|
||||
enable_lifespan=False,
|
||||
):
|
||||
self.application = application
|
||||
self.endpoints = endpoints or []
|
||||
|
|
@ -93,6 +95,9 @@ class Server:
|
|||
if not self.endpoints:
|
||||
logger.error("No endpoints. This server will not listen on anything.")
|
||||
sys.exit(1)
|
||||
self.lifespan_context = None
|
||||
if enable_lifespan:
|
||||
self.lifespan_context = Lifespan(self.application)
|
||||
|
||||
def run(self):
|
||||
# A dict of protocol: {"application_instance":, "connected":, "disconnected":} dicts
|
||||
|
|
@ -120,6 +125,10 @@ class Server:
|
|||
logger.info(
|
||||
"HTTP/2 support not enabled (install the http2 and tls Twisted extras)"
|
||||
)
|
||||
# Set the asyncio reactor's event loop as global
|
||||
# TODO: Should we instead pass the global one into the reactor?
|
||||
evloop = reactor._asyncioEventloop
|
||||
asyncio.set_event_loop(evloop)
|
||||
|
||||
# Kick off the timeout loop
|
||||
reactor.callLater(1, self.application_checker)
|
||||
|
|
@ -133,21 +142,25 @@ class Server:
|
|||
listener.addErrback(self.listen_error)
|
||||
self.listeners.append(listener)
|
||||
|
||||
# Set the asyncio reactor's event loop as global
|
||||
# TODO: Should we instead pass the global one into the reactor?
|
||||
asyncio.set_event_loop(reactor._asyncioEventloop)
|
||||
|
||||
# Verbosity 3 turns on asyncio debug to find those blocking yields
|
||||
if self.verbosity >= 3:
|
||||
asyncio.get_event_loop().set_debug(True)
|
||||
evloop.set_debug(True)
|
||||
|
||||
reactor.addSystemEventTrigger("before", "shutdown", self.kill_all_applications)
|
||||
if not self.abort_start:
|
||||
# Trigger the ready flag if we had one
|
||||
if self.ready_callable:
|
||||
self.ready_callable()
|
||||
# Run the lifespan setup
|
||||
if self.lifespan_context is not None:
|
||||
evloop.run_until_complete(self.lifespan_context.__aenter__())
|
||||
# Run the reactor
|
||||
reactor.run(installSignalHandlers=self.signal_handlers)
|
||||
try:
|
||||
reactor.run(installSignalHandlers=self.signal_handlers)
|
||||
finally:
|
||||
# Execute lifespan cleanup
|
||||
if self.lifespan_context is not None:
|
||||
evloop.run_until_complete(self.lifespan_context.__aexit__())
|
||||
|
||||
def listen_success(self, port):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
name = "daphne"
|
||||
dynamic = ["version"]
|
||||
description = "Django ASGI (HTTP/WebSocket) server"
|
||||
requires-python = ">=3.9"
|
||||
requires-python = ">=3.10"
|
||||
authors = [
|
||||
{ name = "Django Software Foundation", email = "foundation@djangoproject.com" },
|
||||
]
|
||||
|
|
@ -16,7 +16,6 @@ classifiers = [
|
|||
"Operating System :: OS Independent",
|
||||
"Programming Language :: Python",
|
||||
"Programming Language :: Python :: 3",
|
||||
"Programming Language :: Python :: 3.9",
|
||||
"Programming Language :: Python :: 3.10",
|
||||
"Programming Language :: Python :: 3.11",
|
||||
"Programming Language :: Python :: 3.12",
|
||||
|
|
@ -24,7 +23,7 @@ classifiers = [
|
|||
"Topic :: Internet :: WWW/HTTP",
|
||||
]
|
||||
|
||||
dependencies = ["asgiref>=3.5.2,<4", "autobahn>=22.4.2", "twisted[tls]>=22.4"]
|
||||
dependencies = ["asgiref>=3.5.2,<4", "autobahn>=22.4.2", "twisted[tls]>=22.4", "monkay>=0.5.0"]
|
||||
|
||||
[project.optional-dependencies]
|
||||
tests = [
|
||||
|
|
|
|||
|
|
@ -253,6 +253,12 @@ class TestCLIInterface(TestCase):
|
|||
self.assertCLI(["--server-name", ""], {"server_name": ""})
|
||||
self.assertCLI(["--server-name", "python"], {"server_name": "python"})
|
||||
|
||||
def test_enable_lifespan(self):
|
||||
"""
|
||||
Passing `--enable-lifespan` will set enable_lifespan.
|
||||
"""
|
||||
self.assertCLI(["--enable-lifespan"], {"enable_lifespan": True})
|
||||
|
||||
def test_no_servername(self):
|
||||
"""
|
||||
Passing `--no-server-name` will set server name to '' (empty string)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user