Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 16 additions & 12 deletions src/quart/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@
from .utils import file_path_to_path
from .utils import MustReloadError
from .utils import observe_changes
from .utils import restart
from .utils import run_reloader
from .utils import run_sync
from .wrappers import BaseRequestWebsocket
from .wrappers import Request
Expand Down Expand Up @@ -849,6 +849,10 @@ def _signal_handler(*_: Any) -> None:
if port is None:
port = int(sn_port or "5000")

if use_reloader and os.environ.get("QUART_RUN_MAIN") != "true":
run_reloader()
return

task = self.run_task(
host,
port,
Expand All @@ -858,34 +862,34 @@ def _signal_handler(*_: Any) -> None:
keyfile,
shutdown_trigger=shutdown_event.wait, # type: ignore
)
print(f" * Serving Quart app '{self.name}'") # noqa: T201
print(f" * Debug mode: {self.debug or False}") # noqa: T201
print(" * Please use an ASGI server (e.g. Hypercorn) directly in production") # noqa: T201
scheme = "https" if certfile is not None and keyfile is not None else "http"
print(f" * Running on {scheme}://{host}:{port} (CTRL + C to quit)") # noqa: T201

tasks = [loop.create_task(task)]

if use_reloader:
if os.environ.get("QUART_RUN_MAIN") == "true":
tasks.append(
loop.create_task(observe_changes(asyncio.sleep, shutdown_event))
)

reload_ = False
print(f" * Serving Quart app '{self.name}'") # noqa: T201
print(f" * Debug mode: {self.debug or False}") # noqa: T201
print(" * Please use an ASGI server (e.g. Hypercorn) directly in production") # noqa: T201
scheme = "https" if certfile is not None and keyfile is not None else "http"
print(f" * Running on {scheme}://{host}:{port} (CTRL + C to quit)") # noqa: T201

try:
loop.run_until_complete(asyncio.gather(*tasks))
except MustReloadError:
reload_ = True
pass
finally:
try:
_cancel_all_tasks(loop)
loop.run_until_complete(loop.shutdown_asyncgens())
loop.run_until_complete(loop.shutdown_default_executor())
finally:
asyncio.set_event_loop(None)
loop.close()

if reload_:
restart()
if shutdown_event.is_set():
sys.exit(3)

def run_task(
self,
Expand Down
19 changes: 12 additions & 7 deletions src/quart/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import asyncio
import inspect
import os
import subprocess
import sys
from collections.abc import AsyncIterator
from collections.abc import Awaitable
Expand Down Expand Up @@ -135,13 +136,6 @@ async def observe_changes(
last_updates[path] = mtime


def restart() -> None:
# Restart this process (only safe for dev/debug)
executable = sys.executable
args = sys.orig_argv[1:]
os.execv(executable, [executable] + args)


async def cancel_tasks(tasks: set[asyncio.Task]) -> None:
# Cancel any pending, and wait for the cancellation to
# complete i.e. finish any remaining work.
Expand All @@ -156,3 +150,14 @@ def raise_task_exceptions(tasks: set[asyncio.Task]) -> None:
for task in tasks:
if not task.cancelled() and task.exception() is not None:
raise task.exception()


def run_reloader() -> None:
while True:
args = [sys.executable, *sys.orig_argv[1:]]
new_environ = os.environ.copy()
new_environ["QUART_RUN_MAIN"] = "true"
exit_code = subprocess.call(args, env=new_environ, close_fds=False)

if exit_code == 3:
sys.exit(0)
Loading