Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to capture a traceback in gevent

I've spawned a Greenlet and linked it to a callable. Some time later, the Greenlet fails with an Exception. The linked callable gets called. That's all great!

Here's the issue:

The traceback for the Exception appears on my console, as you'd expect. But I want do things with that traceback within the linked callable. How do I get access to that traceback within the linked callable?

(My first instinct was to use traceback.extract_stack(), but it turns out that provides a traceback for the linked callable itself and not for the Exception.)

like image 371
kkurian Avatar asked Feb 13 '12 22:02

kkurian


People also ask

What is a Greenlet in gevent?

Greenlets are lightweight thread-like structures that are scheduled and managed inside the process. They are references to the part of the stack that is used by the thread. Compared to POSIX threads (pthreads), there is no stack allocated up front and there is only as much stack as is actually used by the greenlet.

How does gevent spawn work?

New greenlets are spawned by creating a Greenlet instance and calling its start method. (The gevent. spawn() function is a shortcut that does exactly that). The start method schedules a switch to the greenlet that will happen as soon as the current greenlet gives up control.

Is gevent asynchronous?

Gevent is the use of simple, sequential programming in python to achieve scalability provided by asynchronous IO and lightweight multi-threading (as opposed to the callback-style of programming using Twisted's Deferred).

What is gevent pool?

gevent is a concurrency library based around libev. It provides a clean API for a variety of concurrency and network related tasks.


2 Answers

The traceback is intentionally not saved when the Greenlet dies. If it was saved, it would keep a lot of objects alive that are expected to be deleted, which matters especially if the object manages some resource (open file or socket).

If you want to save the traceback you have to do it yourself.

like image 88
Denis Avatar answered Oct 17 '22 15:10

Denis


As an alternative to Stephen Diehl's solution using 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)
like image 2
Peter Lithammer Avatar answered Oct 17 '22 13:10

Peter Lithammer