Gevent выдает исключение из неправильного потока (greenlet)

Похоже, что Gevent вызывает ошибки, связанные с сетью, в гринлетах, которые в настоящее время не имеют доступа к сети. Вот пример трассировки, в которой для краткости опущены некоторые детали:

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, который, насколько мне известно, не должен попасть в сеть. Под этим я подразумеваю акт создания гринлета не должен влиять на сеть, хотя функция, которая в конечном итоге будет работать в этом гринлете, может попасть в сеть, но я думаю, что мне не нужно беспокоиться об этом. здесь, поскольку в трассировке нет никаких доказательств этого.

Почему gevent вызывает эту, казалось бы, несвязанную сетевую ошибку в этом месте кода? Я подозреваю, что ошибка исходит от другого гринлета, который имеет доступ к сети. Есть ли способ получить реальный контекст трассировки для этой ошибки?

Не уверен, что что-либо из следующего относится к делу, но для контекста:

При запуске процесс исправляет некоторые вещи. Это немного упрощено (фактический код здесь):

from gevent import monkey
from psycogreen.gevent import patch_psycopg

monkey.patch_all(subprocess=True)
patch_psycopg()

Изменить: немного позже он устанавливает gevent.get_hub().SYSTEM_ERROR = BaseException для немедленного закрытия программы в случае сбоя любого гринлета. Может быть, у этого есть другие неожиданные побочные эффекты, такие как эти запутанные трассировки?

Версии системы и библиотеки:

  • Linux djangomanage1-production 4.15.0-1041-aws #43-Ubuntu SMP Чт 6 июня 13:39:11 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
  • Питон 3.6.8
  • получить 1.4.0
  • зеленый 0.4.15

person millerdev    schedule 01.10.2019    source источник
comment
Возможно, связано с github.com/raiden-network/raiden/issues/1829.   -  person millerdev    schedule 01.10.2019


Ответы (1)


Действительно, оказывается, что

gevent.get_hub().SYSTEM_ERROR = BaseException

имеет неожиданные побочные эффекты. socket.gaierror, который был прерывистым, но довольно частым, не возникал с тех пор, как я закомментировал эту строку.

person millerdev    schedule 01.10.2019