adamchainz / django-browser-reload

Automatically reload your browser in development.
MIT License
507 stars 26 forks source link

django-browser-reload prevents uvicorn reload #255

Closed roushikk closed 5 months ago

roushikk commented 5 months ago

Python Version

3.12.2

Django Version

4.2.11

Package Version

1.12.1

Browser

Chrome 123

Description

When django-browser-reload is enabled and we open a connection, it prevents uvicorn reload to trigger. The reload gets stuck on the following for infinite amount of time:

WARNING:  WatchFiles detected changes in 'narcissus/components/meow.py'. Reloading...
INFO:     Shutting down
INFO:     Waiting for connections to close. (CTRL+C to force quit)

Adding --timeout-graceful-shutdown 2 makes the reload possible with the following message:

WARNING:  WatchFiles detected changes in 'narcissus/components/meow.py'. Reloading...
INFO:     Shutting down
INFO:     Waiting for connections to close. (CTRL+C to force quit)
ERROR:    Cancel 1 running task(s), timeout graceful shutdown exceeded   <-- Indicates a running task that is not shutting down on uvicorn reload signal
INFO:     Finished server process [1169]
INFO:     Started server process [2964]
INFO:     Waiting for application startup.
INFO:     ASGI 'lifespan' protocol appears unsupported.
INFO:     Application startup complete.
INFO:     172.18.0.1:51234 - "GET /__reload__/events/ HTTP/1.1" 200 OK

I think the following lines in src/django_browser_reload/views.py might be the reason for this behaviour:

async def event_stream() -> AsyncGenerator[bytes, None]:
    while True:
        await asyncio.sleep(PING_DELAY)
        yield message("ping", versionId=version_id)

        if should_reload_event.is_set():
            should_reload_event.clear()
            yield message("reload")
adamchainz commented 5 months ago

django-browser-reload works by having an infinite streaming response: https://github.com/adamchainz/django-browser-reload#how-it-works . I think you’ll need to find a way to stop uvicorn from waiting for connections to close to make these two tools work together. Not really anything we can do in this package as it’s unaware of the host server’s state.