asgiref: ValueError: set_wakeup_fd only works in main thread
Hello everyone! Related to: 132:
Current situation
My environment is Windows Server 2016, Apache 2.4.39, Python 3.8.1 + mod_wsgi 4.7.1 + Django 3.0.3 + asgiref 3.2.3. I just updated from Django 2.2.10 to 3.0.3 and then my project started to crash with traceback:
[2020-02-20 17:58:04] | MainProcess | ERROR | 222 | django.request | log_response | Internal Server Error: /api/config/
Traceback (most recent call last):
File "C:\Program Files\Python38\Lib\site-packages\django\contrib\auth\middleware.py", line 57, in process_request
username = request.META[self.header]
KeyError: 'REMOTE_USER'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Program Files\Python38\Lib\site-packages\django\core\handlers\exception.py", line 34, in inner
response = get_response(request)
File "C:\Program Files\Python38\Lib\site-packages\django\utils\deprecation.py", line 93, in __call__
response = self.process_request(request)
File "C:\Program Files\Python38\Lib\site-packages\DiffApp\core\common\middleware.py", line 15, in process_request
super(CustomRemoteUserMiddleware, self).process_request(request)
File "C:\Program Files\Python38\Lib\site-packages\django\contrib\auth\middleware.py", line 62, in process_request
if self.force_logout_if_no_header and request.user.is_authenticated:
File "C:\Program Files\Python38\Lib\site-packages\django\utils\functional.py", line 224, in inner
self._setup()
File "C:\Program Files\Python38\Lib\site-packages\django\utils\functional.py", line 360, in _setup
self._wrapped = self._setupfunc()
File "C:\Program Files\Python38\Lib\site-packages\django\contrib\auth\middleware.py", line 24, in <lambda>
request.user = SimpleLazyObject(lambda: get_user(request))
File "C:\Program Files\Python38\Lib\site-packages\django\contrib\auth\middleware.py", line 12, in get_user
request._cached_user = auth.get_user(request)
File "C:\Program Files\Python38\Lib\site-packages\django\contrib\auth\__init__.py", line 180, in get_user
user = backend.get_user(user_id)
File "C:\Program Files\Python38\Lib\site-packages\django\contrib\auth\backends.py", line 161, in get_user
user = UserModel._default_manager.get(pk=user_id)
File "C:\Program Files\Python38\Lib\site-packages\django\db\models\manager.py", line 82, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "C:\Program Files\Python38\Lib\site-packages\django\db\models\query.py", line 411, in get
num = len(clone)
File "C:\Program Files\Python38\Lib\site-packages\django\db\models\query.py", line 258, in __len__
self._fetch_all()
File "C:\Program Files\Python38\Lib\site-packages\django\db\models\query.py", line 1261, in _fetch_all
self._result_cache = list(self._iterable_class(self))
File "C:\Program Files\Python38\Lib\site-packages\django\db\models\query.py", line 57, in __iter__
results = compiler.execute_sql(chunked_fetch=self.chunked_fetch, chunk_size=self.chunk_size)
File "C:\Program Files\Python38\Lib\site-packages\django\db\models\sql\compiler.py", line 1142, in execute_sql
cursor = self.connection.cursor()
File "C:\Program Files\Python38\Lib\site-packages\django\utils\asyncio.py", line 19, in inner
event_loop = asyncio.get_event_loop()
File "C:\Program Files\Python38\lib\asyncio\events.py", line 636, in get_event_loop
self.set_event_loop(self.new_event_loop())
File "C:\Program Files\Python38\lib\asyncio\events.py", line 656, in new_event_loop
return self._loop_factory()
File "C:\Program Files\Python38\lib\asyncio\windows_events.py", line 310, in __init__
super().__init__(proactor)
File "C:\Program Files\Python38\lib\asyncio\proactor_events.py", line 632, in __init__
signal.set_wakeup_fd(self._csock.fileno())
ValueError: set_wakeup_fd only works in main thread
If I reboot Apache several time and if I lucky enough I can enter the proper thread (is is my suggestions) and app is running fine.
Now I have the temporal solution which is to add following lines to asgiref\__init__.py
(as it was suggested in 132:
if sys.platform == "win32" and sys.version_info >= (3, 8, 0):
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Reactions: 5
- Comments: 26 (7 by maintainers)
I would suggest in mod_wsgi config, if on Windows, of using something like:
The use of
application-group
onWSGIScriptAlias
will force pre-loading of the WSGI script file. This preloading should occur in the main thread.What I suspect may be occurring is that the
threading
module isn’t being imported during normal Python interpreter initialisation, and is only subsequently being imported the first time a request arrives, which will be on an external thread (non main thread), as a result themain_thread()
gets initialised to be the external thread and something blows up.Anyway, this is guess as I don’t grok the overall issue as brain not working well enough to get my head around it.
If this solves the problem, I would suggest this is a bug in CPython in that the
threading
module assumes that it is always first imported by the main thread and never another thread.This is fine if the
threading
module is always imported during interpreter/sub interpreter initialisation, but would be a problem if it isn’t guaranteed to be.FWIW, there will be a more permanent workaround for this CPython behaviour in mod_wsgi version 4.8.0 when released.
WSGIScriptAlias / my_path_to_wsgi/wsgi.py application-group=%{GLOBAL}
inside the VirtualHost definition is working fine on Windows 10 like suggested above! Thanks for the Solution!!
You don’t strictly need
WSGIApplicationGroup
as theapplication-group
argument onWSGIScriptAlias
overrides that.