2015-05-21 2 views
0

Я хотел бы услышать решение других людей о проблеме, которую я вижу по умолчанию, которую gevent использует, чтобы сигнализировать о выходе из состояния greenlets.gevent clean Выход Greenlet

Мне нравится возможность делать group.kill (timeout = 3), но способ, которым он переводится в зеленую оболочку, - это генерация GreenletExit. Это отлично подходит для очень простого кода локальных вычислений, но я считаю это очень ограниченным для чего-то более сложного. Вот пример (с использованием ZMQ):

def myGreenlet(zFrom, zTo): 
    msg = zFrom.recv_multipart() 
    zTo.send_multipart(msg) 

Я хотел бы быть в состоянии сказать, мой greenlet, чтобы выйти, но игнорировать GreenletExit, если он находится в середине приема/передачи ничего. Если это так, отправьте сообщение, которое вы получили, и только потом выходите чисто.

GreenletExit - это просто бык в фарфоровом магазине. Таким образом, решение, которое я придумал, чтобы не использовать этот механизм вообще, кроме как последнее обращение, вместо этого я вручную обрабатывать сигнализацию на greenlet, чтобы выйти через событие, как это:

def myGreenlet(stopEvent, zFrom, zTo): 
    while not stopEvent.wait(0): 
     msg = zFrom.recv_multipart() 
     zTo.send_multipart(msg) 

Как вам» Следует отметить, что это не очень хорошо, если я не начну добавлять таймауты во всех своих вызовах ввода-вывода (например, recv) и добавить тайм-аут в .wait(), чтобы замедлить его, что противоречит философии gevent.

Я искал лучшие решения, документально оформленные, но им не повезло. Каков общий консенсус, какие-либо хорошо поддерживаемые методы для такого рода проблем?

+0

Очевидно, что для второго примера я мог бы также сделать выбор между zFrom и stopEvent, но она по-прежнему кажется, как много дополнительного кода для проблемы, которая должна быть довольно распространенной. – user3395838

+0

Является ли мой ответ для вас источником вдохновения? Если да, примите мой ответ, это важно для меня. Спасибо. – liushuaikobe

ответ

0

Более разумный способ решить эту проблему может позволить каждой родословной обрабатывать свое собственное исключение таймаута. Координатор ролетки не должен выполнять слишком много вмешательства на зеленых. То, что должен сделать координатор, это joinall из них, а затем спросить зелья для результата или исключения, от которого это зависит, чтобы выполнить некоторые последующие действия.

Чтобы подробно объяснить:

def my_greenlet(): 
    try: 
     # do something here... 
    except KindOfTimeOutException, e: 
     raise e 

Координатор greenlets:

greenlets = [gevent.spawn(my_greenlet) for i range(10)] 
gevent.joinall(greenlets) 

# NOTE: On this time, the greenlets all have quit by themselves 
for greenlet in greenlets: 
    e = greenlet.exception 
    if e: 
     # handle exception... 
    else: 
     result = greenlet.value 
     # do something... 
+0

@ user3395838 «это вводит слишком много связей между координатором и зеленью», это то, что я хочу сказать вам о вашем вопросе. В моем ответе я позволял зелень обрабатывать исключение самостоятельно, и координатор проверяет результат. – liushuaikobe

+0

@ user3395838 Нет никакого противоречия между моим решением и вашим случаем. Актер мог присоединиться к зелени и проверить результаты, а затем решить, будет ли появляться несколько новых зеленых. – liushuaikobe

Смежные вопросы