gevent найти родительский гринлет

Есть ли способ узнать, из какого гринлета был создан текущий гринлет в gevent?

  1. Я понимаю, что гринлет, который породил текущий гринлет, возможно, уже завершился, но в этом случае я был бы в порядке с обработкой None в качестве ответа.
  2. Я знаю о gevent.Greenlet.parent, но он представляет собой только концентратор, а не прямой гринлет, с которого был запущен текущий гринлет.
  3. Я бы предпочел решение, которое не требует исправления обезьяны gevent.Greenlet

Мой вариант использования: у меня есть сервер, который обрабатывает запросы на выполнение кода Python (да, да, я знаю, что это небезопасно :-). Каждый запрос порождает гринлет, который обрабатывает запрос, включая перенаправление любого ввода, вывода или ошибки на канал, закрытый для запроса. Я хочу иметь возможность обрабатывать запросы одновременно, и запросы могут сами порождать гринлеты.

Вы можете найти пример того, что я пытаюсь сделать здесь


person Tiago Coutinho    schedule 11.11.2016    source источник


Ответы (1)


В оригинальном пакете greenlet создание нового объекта greenlet имеет следующую подпись greenlet(run=None, parent=None). Таким образом, это означает, что вы можете указать parent аргумент или оставить его None, а гринлет по умолчанию назначает функцию вызывающего абонента.

В дополнение к этому пакету gevent предоставляет инструменты и крошечный цикл обработки событий, который управляет поведением гринлетов и жизненным циклом . Таким образом, любой гринлет, созданный gevent.spawn или gevent.Greenlet, автоматически наследует текущий концентратор (цикл событий) в качестве родителя. Таким образом, каждый раз, когда один гринлет завершает свое выполнение, он передает управление обратно в цикл обработки событий. Согласно документации: «Это позволяет гринлету выполнять некоторые действия по очистке, прежде чем передать контроль».

Однако, просмотрев документацию и исходный код инициализации Greenlet, я вижу, что все еще возможно переопределить конструктор, предоставив новые аргументы.

from gevent.greenlet import Greenlet as GeventGreenlet


class Greenlet(GeventGreenlet):

    def __init__(self, caller=None, *args, **kwargs):
        super(Greenlet, self).__init__(*args, **kwargs)
        self._caller = caller

Затем вам нужно указать пакету greenlet использовать вашу реализацию Greenlet (аналогично gevent monkeypatch) как можно раньше.

import gevent.greenlet
from myapp.greenlet import Greenlet

gevent.greenlet.Greenlet = Greenlet
person Rustem K    schedule 13.11.2016
comment
Я уже избегаю использования исправлений обезьяны gevent, поэтому я бы предпочел решение, которое не включает в себя исправление обезьяны самого gevent - person Tiago Coutinho; 18.11.2016