-
-
Notifications
You must be signed in to change notification settings - Fork 2k
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
Make GunicornWebWorker exit with APP_LOAD_ERROR in case of a startup error #6968
base: master
Are you sure you want to change the base?
Conversation
aiohttp/worker.py
Outdated
@@ -55,6 +56,9 @@ def run(self) -> None: | |||
self.loop.run_until_complete(self._task) | |||
except Exception: | |||
self.log.exception("Exception in gunicorn worker") | |||
self.booted = False | |||
self.exit_code = Arbiter.WORKER_BOOT_ERROR |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, the gunicorn code seems to set self.booted = True
before it calls .run()
. This suggests to me that it is about recording whether the process was created, rather than whether the application startup succeeded. This seems to me like it should probably exit 1 instead.
If this was how gunicorn was supposed to work, then I'd expect booted
to still be False
and then we would set it to True
in _run()
after the setup is complete (line 95).
Looking at some of the other workers, I'm also noticing gtornado using alive
and server_alive
, not sure if something like that is more appropriate:
https://github.com/benoitc/gunicorn/blob/master/gunicorn/workers/gtornado.py#L91-L92
Also wondering if we should actually be using the AsyncWorker
as our base class:
https://github.com/benoitc/gunicorn/blob/master/gunicorn/workers/base_async.py
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In fact there is an APP_LOAD_ERROR, which sounds a lot more accurate for this situation:
https://github.com/benoitc/gunicorn/blob/master/gunicorn/arbiter.py#L34
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've been thinking about using APP_LOAD_ERROR before, but decided to stay with WORKER_BOOT_ERROR (I didn't know when we can say the app is loaded, but the same problem I have got with a worker). Nevertheless you are probably right about setting booted
to False
after it has already been set to True
, so APP_LOAD_ERROR seems to be correct.
I will take a look at the other workers to have a bit more knowledge.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(I didn't know when we can say the app is loaded, but the same problem I have got with a worker).
When the setup has completed on line 95, the application has been initialised. If we go this way, then I'd suggest adding a self.started = False
and setting it to True
after site.start()
on line 105. Then only set this exit status if not self.started
, otherwise a 1
is probably a reasonable exit code (likely indicating that an exception happened in the app's cleanup).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm hoping one of the gunicorn maintainers might provide some feedback, but if we don't hear anything back in a few days, then this looks reasonable to me.
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #6968 +/- ##
=======================================
Coverage 97.31% 97.31%
=======================================
Files 107 107
Lines 31485 31489 +4
Branches 3937 3937
=======================================
+ Hits 30640 30644 +4
Misses 641 641
Partials 204 204
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
…not. This way we are able to select correct exit_code for the worker.
0c05ebb
to
a7bb898
Compare
OK, they have provided feedback now. Sounds like this is not the desired approach: |
Make GunicornWebWorker exit with WORKER_BOOT_ERROR (3) in case of an boot error.
I've found out that
GunicornWebWorker
exits with0
error code even when an error occurs during startup. This makes Gunicorn endlessly spawn new workers.With this pull request I would like to show the problem and ask if there is any other solution. I am aware of the comment
# ignore all finalization problems
and would like to ask about the context of this comment.What do these changes do?
These changes set
GunicornWebWorker.exit_code
to the value expected by the Gunicorn, which is3
and setGunicornWebWorker.booted
to false.Checklist
CONTRIBUTORS.txt
CHANGES
folder<issue_id>.<type>
for example (588.bugfix)issue_id
change it to the pr id after creating the pr.feature
: Signifying a new feature..bugfix
: Signifying a bug fix..doc
: Signifying a documentation improvement..removal
: Signifying a deprecation or removal of public API..misc
: A ticket has been closed, but it is not of interest to users.