Gevent 从错误的线程(greenlet)抛出异常
Gevent throws exception from wrong thread (greenlet)
Gevent 似乎在当前未访问网络的 greenlet 中引发与网络相关的错误。这是一个示例回溯,为简洁起见省略了一些细节:
Traceback (most recent call last):
...
File ".../asyncforms.py", line 95, in _try_to_process_form
self.pool.spawn(self._async_migrate_form, wrapped_form, case_ids)
File ".../lib/python3.6/site-packages/gevent/pool.py", line 391, in spawn
self.start(greenlet)
File ".../lib/python3.6/site-packages/gevent/pool.py", line 601, in start
self.add(greenlet, *args, **kwargs)
File ".../lib/python3.6/site-packages/gevent/pool.py", line 634, in add
if not self._semaphore.acquire(blocking=blocking, timeout=timeout):
File "src/gevent/_semaphore.py", line 100, in gevent.__semaphore.Semaphore.acquire
File "src/gevent/_semaphore.py", line 128, in gevent.__semaphore.Semaphore.acquire
File "src/gevent/_abstract_linkable.py", line 192, in gevent.__abstract_linkable.AbstractLinkable._wait
File "src/gevent/_abstract_linkable.py", line 165, in gevent.__abstract_linkable.AbstractLinkable._wait_core
File "src/gevent/_abstract_linkable.py", line 169, in gevent.__abstract_linkable.AbstractLinkable._wait_core
File "src/gevent/_greenlet_primitives.py", line 60, in gevent.__greenlet_primitives.SwitchOutGreenletWithLoop.switch
File "src/gevent/_greenlet_primitives.py", line 60, in gevent.__greenlet_primitives.SwitchOutGreenletWithLoop.switch
File "src/gevent/_greenlet_primitives.py", line 64, in gevent.__greenlet_primitives.SwitchOutGreenletWithLoop.switch
File "src/gevent/__greenlet_primitives.pxd", line 35, in gevent.__greenlet_primitives._greenlet_switch
socket.gaierror: [Errno -9] Address family for hostname not supported
如您所见,当前线程是 gevent.pool.Pool
中的 spawning a new greenlet,据我所知,该线程不应访问网络。我的意思是 产生一个 greenlet 的行为不应该进入网络 ,尽管那个 greenlet 中最终 运行 的函数可能会进入网络,但我想我做到了在这里不需要担心,因为在回溯中没有证据。
为什么 gevent 在代码的这个地方引发这个看似无关的网络错误?我怀疑错误来自另一个 is 访问网络的 greenlet。有没有办法获取此错误的真实回溯上下文?
不确定以下任何一项是否相关,但对于上下文:
启动时,进程会修补一些东西。这有点简化(实际代码here):
from gevent import monkey
from psycogreen.gevent import patch_psycopg
monkey.patch_all(subprocess=True)
patch_psycopg()
编辑:a bit later 它设置 gevent.get_hub().SYSTEM_ERROR = BaseException
使程序在任何 greenlet 崩溃时立即退出。也许这还有其他意想不到的副作用,例如这些令人困惑的回溯?
系统和库版本:
- Linux djangomanage1-production 4.15.0-1041-aws #43-Ubuntu SMP Thu Jun 6 13:39:11 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
- Python 3.6.8
- gevent 1.4.0
- greenlet 0.4.15
的确如此
gevent.get_hub().SYSTEM_ERROR = BaseException
有意想不到的副作用。 socket.gaierror
,断断续续但相当频繁,自从我注释掉该行后就没有发生过。
Gevent 似乎在当前未访问网络的 greenlet 中引发与网络相关的错误。这是一个示例回溯,为简洁起见省略了一些细节:
Traceback (most recent call last):
...
File ".../asyncforms.py", line 95, in _try_to_process_form
self.pool.spawn(self._async_migrate_form, wrapped_form, case_ids)
File ".../lib/python3.6/site-packages/gevent/pool.py", line 391, in spawn
self.start(greenlet)
File ".../lib/python3.6/site-packages/gevent/pool.py", line 601, in start
self.add(greenlet, *args, **kwargs)
File ".../lib/python3.6/site-packages/gevent/pool.py", line 634, in add
if not self._semaphore.acquire(blocking=blocking, timeout=timeout):
File "src/gevent/_semaphore.py", line 100, in gevent.__semaphore.Semaphore.acquire
File "src/gevent/_semaphore.py", line 128, in gevent.__semaphore.Semaphore.acquire
File "src/gevent/_abstract_linkable.py", line 192, in gevent.__abstract_linkable.AbstractLinkable._wait
File "src/gevent/_abstract_linkable.py", line 165, in gevent.__abstract_linkable.AbstractLinkable._wait_core
File "src/gevent/_abstract_linkable.py", line 169, in gevent.__abstract_linkable.AbstractLinkable._wait_core
File "src/gevent/_greenlet_primitives.py", line 60, in gevent.__greenlet_primitives.SwitchOutGreenletWithLoop.switch
File "src/gevent/_greenlet_primitives.py", line 60, in gevent.__greenlet_primitives.SwitchOutGreenletWithLoop.switch
File "src/gevent/_greenlet_primitives.py", line 64, in gevent.__greenlet_primitives.SwitchOutGreenletWithLoop.switch
File "src/gevent/__greenlet_primitives.pxd", line 35, in gevent.__greenlet_primitives._greenlet_switch
socket.gaierror: [Errno -9] Address family for hostname not supported
如您所见,当前线程是 gevent.pool.Pool
中的 spawning a new greenlet,据我所知,该线程不应访问网络。我的意思是 产生一个 greenlet 的行为不应该进入网络 ,尽管那个 greenlet 中最终 运行 的函数可能会进入网络,但我想我做到了在这里不需要担心,因为在回溯中没有证据。
为什么 gevent 在代码的这个地方引发这个看似无关的网络错误?我怀疑错误来自另一个 is 访问网络的 greenlet。有没有办法获取此错误的真实回溯上下文?
不确定以下任何一项是否相关,但对于上下文:
启动时,进程会修补一些东西。这有点简化(实际代码here):
from gevent import monkey
from psycogreen.gevent import patch_psycopg
monkey.patch_all(subprocess=True)
patch_psycopg()
编辑:a bit later 它设置 gevent.get_hub().SYSTEM_ERROR = BaseException
使程序在任何 greenlet 崩溃时立即退出。也许这还有其他意想不到的副作用,例如这些令人困惑的回溯?
系统和库版本:
- Linux djangomanage1-production 4.15.0-1041-aws #43-Ubuntu SMP Thu Jun 6 13:39:11 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
- Python 3.6.8
- gevent 1.4.0
- greenlet 0.4.15
的确如此
gevent.get_hub().SYSTEM_ERROR = BaseException
有意想不到的副作用。 socket.gaierror
,断断续续但相当频繁,自从我注释掉该行后就没有发生过。