[Twisted-web] using @defer.inlineCallbacks and yield correctly

Stephan schenette at gmail.com
Thu Sep 1 02:34:12 EDT 2011


I'm sending this email to separate out the two issues I'm having to
gain a better understanding of how to properly code what I'm
attempting to do.

I'd like to use spawnProcess to spawn a process but with a timeout. If
the timeout is reached I'd like to kill the process. You can see in
the error section that I'm getting an error with defer and no yield. I
was hoping someone could tell me what my code is supposed to do that
it's not doing so that I can stop getting the error found at the
bottom.

from what I understand  @defer.inlineCallbacks is used to defer a
async callback function like how i'm using CallLater below, but where
is the yield supposed to be? and how should the below code change?

========================
Code
========================

        command = "xvfb-run --auto-servernum firefox -P %s" % profile_id
        logging.debug("command: %s", command)
        args = shlex.split(command)

        self.pp = TimedProcessProtocol(self, 100)
        subprocess = reactor.spawnProcess(self.pp, args[0], args, env
= os.environ, usePTY=1)
        logging.debug("spawned a process: pid: %d", subprocess.pid)
        self.pid = subprocess.pid

========================
ProcessProtocol Class
========================

class TimedProcessProtocol(protocol.ProcessProtocol):

    def __init__(self, firefoxProcess, timeout):
        self.timeout = timeout
        self.firefoxProcess = firefoxProcess
        self.killed = None

    def isProcessDead(self):
        logging.debug("isProcessDead called")
        if self.killed is None:
            return False
        else:
            logging.debug("process is dead!!__________")
            return True

    def killProcessIfAlive(self):
        logging.debug("killProcessIfAlive called")
        #@defer.inlineCallbacks
        try:
            #yield self.transport.signalProcess('KILL')
            if self.killed is None:
                os.kill(-self.transport.pid, signal.SIGTERM)
        except error.ProcessExitedAlready:
            logging.debug("process already exited")
            pass

    def connectionMade(self):
        logging.debug("connection made timeout = %d", self.timeout)
        @defer.inlineCallbacks
        def onTimer():
            logging.debug("timeout triggered")
            self.firefoxProcess.handleProcessTimedOut()
            self.killProcessIfAlive()
        d = reactor.callLater(self.timeout, onTimer)


========================
Errors
========================

2011-08-31 12:30:22-0700 [-] Unhandled error in Deferred:
2011-08-31 12:30:22-0700 [-] Unhandled Error
   Traceback (most recent call last):
     File "/usr/lib/python2.6/dist-packages/twisted/internet/base.py",
line 1170, in run
       self.mainLoop()
     File "/usr/lib/python2.6/dist-packages/twisted/internet/base.py",
line 1179, in mainLoop
       self.runUntilCurrent()
     File "/usr/lib/python2.6/dist-packages/twisted/internet/base.py",
line 778, in runUntilCurrent
       call.func(*call.args, **call.kw)
     File "/usr/lib/python2.6/dist-packages/twisted/internet/defer.py",
line 944, in unwindGenerator
       return _inlineCallbacks(None, f(*args, **kwargs), Deferred())
   --- <exception caught here> ---
     File "/usr/lib/python2.6/dist-packages/twisted/internet/defer.py",
line 823, in _inlineCallbacks
3, in _inlineCallbacks
       result = g.send(result)
   exceptions.AttributeError: 'NoneType' object has no attribute 'send'



More information about the Twisted-web mailing list