2012-02-13 15 views
6

में ट्रेसबैक कैप्चर करने के लिए कैसे मैंने एक ग्रीनलेट बनाया है और इसे एक कॉल करने योग्य से जोड़ा है। कुछ समय बाद, ग्रीनलेट एक अपवाद के साथ विफल रहता है। जुड़ा हुआ कॉल करने योग्य कहा जाता है। यह सब अच्छा है! ,गीवेंट

अपवाद के लिए ट्रैस बैक मेरे कंसोल पर प्रकट होता है के रूप में आप उम्मीद थी:

यहाँ मुद्दा है। लेकिन मैं लिंक किए गए कॉल करने योग्य के भीतर उस ट्रेसबैक के साथ चीजें करना चाहता हूं। मैं लिंक किए गए कॉल करने योग्य के भीतर उस ट्रेसबैक तक पहुंच कैसे प्राप्त करूं?

(मेरी पहली वृत्ति traceback.extract_stack() उपयोग करने के लिए था, लेकिन यह पता चला है कि जुड़ा हुआ प्रतिदेय खुद के लिए और अपवाद के लिए नहीं ट्रैसबैक प्रदान करता है।)

उत्तर

15

ग्रीनलेट मरने पर ट्रेसबैक जानबूझकर सहेजा नहीं जाता है। यदि यह सहेजा गया था, तो यह बहुत सारी वस्तुओं को जीवित रखेगा जिन्हें हटाया जाने की उम्मीद है, विशेष रूप से यदि वस्तु कुछ संसाधन (खुली फ़ाइल या सॉकेट) का प्रबंधन करती है।

यदि आप ट्रेसबैक को सहेजना चाहते हैं तो आपको इसे स्वयं करना होगा।

+1

और यह एक आधिकारिक उत्तर है। धन्यवाद, डेनिस। – kkurian

1

बस सुनिश्चित करें कि आप Greenlet की exception मूल्य हड़पने और get रिटर्न या तो मान दिया, Greenlet बाहर फेंक उदाहरण के लिए या अंतरराष्ट्रीय उठाती बनाने एल अपवाद।

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(); ; <अब हम बार में हैं()>) - बार() के भीतर जो सुझाव दिया गया है, वह अपवाद के लिए ट्रेसबैक उत्पन्न नहीं करता है क्योंकि इसे foo में उठाया गया था, यह अपवाद के लिए ट्रेसबैक उत्पन्न करता है क्योंकि यह बार में उठाया जाता है। – kkurian

+0

शायद आपको ऊपर अपना कोड पेस्ट करना चाहिए, आपकी समस्या एक स्कोपिंग समस्या प्रतीत होती है और यदि हम देख सकते हैं कि आप अपने स्कॉप्स को कैसे सेट अप कर रहे हैं तो डीबग करना आसान होगा। –

0

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