Replies: 1 comment
-
Hi @davidism - I saw you converted this from a bug to a discussion. Do you think this might be better suited for gunicorn instead of flask? This is a really annoying bug, which brings development to a complete halt. It was also difficult and time consuming to isolate and replicate. I assume that if I post this over to gunicorn they are going to tell me that the issue is with Flask, because this only happens when using blueprints. |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
This is a very interesting bug.
When using Blueprints with flask, and importing something into gunicorn.conf.py from the same top level module in which the flask application resides, Gunicorn's --reload functionality breaks. Specifically, the reloading functionality appears to work- gunicorn informs us that the application has been reloaded; but the run time code is actually cached, and the application in effect does not reload.
This bug is an issue because it makes development inconvenient, and it is time consuming to isolate.
This bug cannot be replicated if:
The reason I believe this is a flask bug, instead of a gunicorn bug, is that this bug only exists when using blueprints.
I've replicated this on Python 3.11.5, Flask 2.3.3 and 2.0.0, Gunicorn 21.2.0 and 21.0.0, and RHEL and Ubuntu.
Docker
I've uploaded a repo with a Dockerfile and docker-compose.yaml that can be used to quickly reproduce the bug. The application runs on port 8080.
Directory Structure
blueprintbug/app/init.py
blueprintbug/gunicorn.conf.py
blueprintbug/requirements.txt
Running the application
Run the application with the reload option:
With the above code, if we call GET /, we can see the following exception, which we expect:
Now let's change
blueprintbug/app/__init__.py
to raisebar
instead offoo
:And we can confirm that gunicorn appears to have reloaded the application:
Next we can call
GET /
which will result in this strange result:Notice how the stack trace says
raise Exception("bar")
, but how the actual run time exception raised isfoo
.This implies that gunicorn is caching the run time code, even though it recognizes that the code has changed.
We would have expected the following console output, which does not happen:
The quickest workaround appears to be using lazy loading inside of
gunicorn.conf.py
.Alternatively, you can move the
init_application
andcleanup_application
to a separate directory from/app
.Or you can not use blueprints.
Beta Was this translation helpful? Give feedback.
All reactions