using @defer.inlineCallbacks and yield correctly

Stephan <[email protected]>
Newsgroups gmane.comp.python.twisted.web
Message-ID <CADozHMXLhaHPO4OVJN4ee=hdi+RYhdXQ-eSLcz0wdUbc08aa+A@mail.gmail.com>
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'
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.