I need to inject thread level context information for logging and debugging purposes. I've been told that this is potentially unsafe.
greenthread = worker_pool.spawn(run_worker, args, handle_result)
# this logging_context attribute will be accessed by the logging library
greenthread.__dict__['logging_context'] = 'data for logging'
greenthread.link()
While certainly not something you would want to do often, it was the only way I could set a thread local global constant, which the logger could access.
This can then be accessed later by the logger via
eventlet.getcurrent().logging_context
As far as my knowledge in python goes, I don't see how this is unsafe, why do others say this is potentially a recipe for disaster?
While I see it as a rather ugly monkey patch, I am not creating global mutable state. I am creating a thread-local constant that is instantiated before the thread is even run.
I agree, "safe/unsafe" is for obsessed parents. As programmers we can define expectancy for troubles in a much more strict and useful way.
spawn
. Right now it takes sleep()
or other way to yield to "event loop" before newly spawned greenthread executes, but that behavior may change in future. Which means that run_worker
may already be running. You can use eventlet.pools.Pool()
to manage proper setup and link of greenthreads before allowing them to run.__slots__
to save memory, or particular __setattr__
implementation for other reasons.threading
[1].Sample code for threadlocal
route:
def add_logging_context(context, fun, *a, **kw):
tl = threading.local()
tl.logging_context = context
return fun(*a, **kw)
pool.spawn(add_logging_context, 'data for logging', run_worker, args, handle_result)