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.)
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.
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.
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).
gevent is a concurrency library based around libev. It provides a clean API for a variety of concurrency and network related tasks.
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.
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With