aborilov
aborilov

Reputation: 8724

Using context in twisted

I try to use twisted.python.context, but context disappear after first deferToThread.

from twisted.internet import reactor, defer, threads
from twisted.python import context

def _print_context(msg):
    cont = context.get('cont')
    print "{msg}: {context}".format(msg=msg, context=cont)

def sub_call():
    _print_context("In sub_call")

@defer.inlineCallbacks
def with_context():
    _print_context("before thread")
    yield threads.deferToThread(sub_call)
    _print_context("after thread")
    reactor.stop()

def test():
    cont = {'cont': "TestContext"}
    context.call(cont, with_context)
reactor.callLater(0, test)
reactor.run()

I have context before deferToThread and in sub_call, but no context after deferToThread.

Is there any way to have context after deferToThread?

Upvotes: 1

Views: 840

Answers (1)

Jean-Paul Calderone
Jean-Paul Calderone

Reputation: 48335

context.call sets the context for the duration of the call of the object passed to it - in this case with_context.

with_context is an inlineCallbacks-wrapped generator function. The first call to it creates a new generator and iterates it as far as the first yield statement. Then its execution is suspended and, as far as the caller is concerned, the call returns. At this point the context stack is popped and the context you supplied is discarded.

Later, the implementation of inlineCallbacks ensures the generator will be iterated further so that the code after the yield statement executes. However, the context has already been discarded.

There's no easy way to fix this. twisted.python.context does not try to address the problem of asynchronous context management. Moreover, twisted.python.context is fairly terrible and few if any programs should actually be written to use it.

I recommend taking a step back and re-evaluating your choice here. You'd probably be better served by creating a class and using instance attributes on an instance of it to carry state around between method calls.

Upvotes: 4

Related Questions