I'm trying to get to the bottom of a weird bug (see here) - basically I'm seeing unexpected DB disconnects. To investigate I added a call stack dump to the disconnect code in Django - now I'm more confused than ever...
What I'm seeing in the call stack is a completely unexpected call sequence, e.g.:
...
File "/deployment/v_env/lib/python3.8/site-packages/qrcode/base.py", line 326, in __mod__
for item, other_item in zip(self, other)]
File "/deployment/v_env/lib/python3.8/site-packages/qrcode/base.py", line 303, in __iter__
return iter(self.num)
File "/deployment/v_env/lib/python3.8/site-packages/django/http/response.py", line 292, in close
signals.request_finished.send(sender=self._handler_class)
File "/deployment/v_env/lib/python3.8/site-packages/django/dispatch/dispatcher.py", line 180, in send
return [
...
Here the QR code library I'm using suddenly jumps to HttpResponse.close(). Another:
...
File "/deployment/v_env/lib/python3.8/site-packages/django/db/models/query.py", line 1268, in _insert
query = sql.InsertQuery(self.model, ignore_conflicts=ignore_conflicts)
File "/deployment/v_env/lib/python3.8/site-packages/django/db/models/sql/subqueries.py", line 141, in __init__
super().__init__(*args, **kwargs)
File "/deployment/v_env/lib/python3.8/site-packages/django/http/response.py", line 292, in close
signals.request_finished.send(sender=self._handler_class)
File "/deployment/v_env/lib/python3.8/site-packages/django/dispatch/dispatcher.py", line 180, in send
return [
...
Here some Django DB query code suddenly jumps to HttpResponse.close().
There's no way that this call stack is right - the code immediately above close() simply does not call that code, nor does it call a close() method that may somehow be bound to the wrong object.
Now HttpResponse.close() can be called by uWSGI from the C runtime - the only thing I can figure is that this is happening during the handling of a request, and somehow this is showing up in the call stack.
So my question is, can this is really the case? Does a C call into python really just jump into the call stack like this, or is uWSGI failing to protect the call to Python correctly? I understand the GIL must be acquired before any call to python - maybe that isn't happening. Or maybe traceback.print_stack()
doesn't handle calls from C properly?
Any insight apeciated.
CodePudding user response:
Thinking some more, I think this injection into the call stack is correct. How else could it work? The GIL could be obtained at any time, and Python isn’t going to start a new interpreter per call, so it’s got to just run in the current context.