2012-02-13 3 views
6

Я породил Greenlet и связал его с вызываемым. Спустя некоторое время Гринлет терпит неудачу с Исключением. Вызывается связанный вызываемый. Это здорово!как захватить трассировку в gevent

Вот вопрос:

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

(Мой первый инстинкт должен был использовать traceback.extract_stack(), но оказывается, что обеспечивает отслеживающий для связанного отзывной себя и не для Exception.)

ответ

15

Отслеживание намеренно не сохраняется, когда Гринлет умирает. Если бы он был сохранен, он сохранил бы много живых объектов, которые, как ожидается, будут удалены, что особенно важно, если объект управляет некоторым ресурсом (открытым файлом или сокетом).

Если вы хотите сохранить трассировку, вам нужно сделать это самостоятельно.

+1

И ЭТО ОТВЕТСТВЕННЫЙ ОТВЕТ. Спасибо, Денис. – kkurian

1

Просто убедитесь, что вы хватаете значение Greenlet exception и выбросить его за пределы Greenlet, например get возвращает либо значение, возвращаемое или поднимает интерны исключение.

import traceback 
import gevent 

def fail(): 
    return 0/0 

gl = gevent.spawn(fail) 

try: 
    gl.get() 
except Exception as e: 
    stack_trace = traceback.format_exc() # here's your stacktrace 

Должно предоставить вам то, что вам нужно.

+0

Я пытаюсь получить трассировку внутри связанного вызываемого (например, foo = gevent.Greenlet (x); foo.link_exception (bar); foo.start(); ; <теперь мы находимся в bar()>) - то, что вы предложили в bar(), не создает трассировку для Exception, поскольку она была поднята в foo, она создает трассировку для Exception, поскольку она поднята в баре. – kkurian

+0

Возможно, вы должны вставить свой код выше, проблема связана с проблемой определения области обзора, и было бы легче отладить, если бы мы могли видеть, как вы настраиваете свои области. –

0

В качестве альтернативы решению Stephen Diehl с использованием Greenlet.link_exception.

import traceback 

import gevent 

def job(): 
    raise Exception('ooops') 

def on_exception(greenlet): 
    try: 
     greenlet.get() 
    except Exception: 
     err = traceback.format_exc() 
     # Do something with `err` 

g = gevent.spawn(job) 
g.link_exception(on_exception) 
+0

Затем вы создадите ссылку, а не создадите, перейдете и начнете? Есть ли какая-то практическая разница? – kkurian

+0

И это касается проблем, которые я поднял в комментариях к решению Диля? – kkurian

+0

Ну, я думаю, что теоретически зелень может потерпеть крах, прежде чем связь будет создана таким образом. – renstrm

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