[Twisted-Python] process status

Daniel Isenegger disen at geo.unizh.ch
Tue Aug 2 13:10:39 EDT 2005


How to query process state and receive back control?

Hi,
a  newbie question: i struggle with the defer-mechanism.
i start from a client program a using defers a 
protocol.ProcessProtocol-class to invoke a local application (grass) to 
display a raster.
This works fine, the problem is now how to propagate back the final 
state of the invoked process back to the invoking instance and then to 
get the control back over the shell the process has been running in.

I can see that the state of the invoked process can be accesses in 
processEnded(), but when this function is invoked the connection to the 
invoking instance is already closed, so the state cannot be propagated 
to this invoking instance.

Additionaly the shell the process has been invoked does not receive 
further output of the invoking process., so i assume that the control is 
not handed back to the invoking process

Any hints?
Thanks Dani

In the following some excerpts of code to illustrate my problem:
 
invoking process:
#############################################################
    # invokes GIS to display the raster cmd, using IpodlasProcess to
    # call a process on the machine
    def displayRaster(self):
        
        # init deferred object d
        d = defer.Deferred()
        # add the pair of callbacks
        d.addCallback(self.handleDisplayRaster)
        d.addErrback(self.handleDisplayRasterFailure)
        #
        #invoke the deferred functions: i.e. handleDisplayRaster
        # and handleDisplayRasterFailure
        d.callback(rasterfile)
        print "displayRaster: after d.callback()"
    #
 ############################################################
    # handles the successfull call of the display of the raster theRaster
    def handleDisplayRaster(self,theRaster):
        #
        # init IpodlasProcess
        ip = IpodlasProcess()
        #
        #
        # invoke IpodlasProcess to invoke Grass to display the raster 
theRaster
        ip.displayRaster(theRaster)
        #
 #########################################################
    # handles the failed call of the display of the file theFoile
    # and its return object theFailure
    def handleDisplayRasterFailure(self,theFailure):
        #
        theFailure.trap(RuntimeError)
        #
###############################################################################
# IpodlasClientFactory is derived from ReconnectingClientFactory, which 
tries
# to reconnect if connection is lost
class IpodlasClientFactory(ReconnectingClientFactory):
    # creates protocol and receives events relating to connection state
    #
    def startedConnecting(self, connector):
        print 'Started to connect.'

    def buildProtocol(self, addr):
        print 'Connected.'
        print 'Resetting reconnection delay'
        self.resetDelay()
        # associated subsystem is the GUI
        return IpodlasClient()

    def clientConnectionLost(self, connector, reason):
        print 'Lost connection.  Reason:', reason
        # tries to reconnect, if conn fails with exponentially delays
        ReconnectingClientFactory.clientConnectionLost(self, connector, 
reason)
    #
    # if connection could not be established
    def clientConnectionFailed(self, connector, reason):
        print 'Connection failed. Reason:', reason
        ReconnectingClientFactory.clientConnectionFailed(self, connector,
                                                         reason)

###################################################################
if __name__ == "__main__":
    #
    if len(sys.argv) > 1:
        # set global subsystem
        assoSubsys = sys.argv[1]
        #print assoSubsys
    #
    from twisted.internet import reactor
    reactor.connectTCP("localhost",51423,IpodlasClientFactory())
    reactor.run()




invoked Process:
#! /usr/bin/python
# File:ipodlasProcess.py

"""
ipodlasProcess.py
usage: python ipodlasProcess.py
"""

from twisted.internet import protocol
from twisted.internet import reactor
from twisted.internet import utils #needed to query process termination 
status
import re
import os
import gc
# own classes

class IpodlasProcess(protocol.ProcessProtocol):
    def __init__(self):
        self.data = ""
        #
    #
    def connectionMade(self):
        print "IP connectionMade"
        self.transport.closeStdin()
    # data from standard output is receieve in outReceived.
    def outReceived(self, data):
        print "IP outReceived: " + self.data
        self.data = self.data + data
    #
    def errReceived(self, data):
        print "IP errReceived():" + data
    #
    def inConnectionLost(self):
        print "IP inConnectionLost! stdin is closed! (we probably did it)"
    #
    def outConnectionLost(self):
        print "IP outConnectionLost data: " + self.data
    #
    def errConnectionLost(self):
        print "IP errConnectionLost! stdin is closed! (we probably did it)"
    #
    def processEnded(self, status_object):
        self.processStatus = status_object.value.exitCode
        print "IP processEnded, status: " + 
str(status_object.value.exitCode) \
              + "\nquitting "
        # this is outcommented, since otherwise the reactor of 
ipodlasClient would
        # stopped, since this is the one which controls ipodlasProcess 
(the own in
        # the main fctn is only started, when invoked from cmd-line)
        # reactor.stop
        
    #
    def displayRaster(self,theRaster):
        #
        cmd = "d.rast"
        arg1 = theRaster
        arg2 = "bg=white"
        # processes are runned trough reactor using spawnProcess
        # invoke process cmd with the args arg1, arg2 and the parent process
        # environment env
        reactor.spawnProcess(self,cmd,[cmd,arg1,arg2],env=os.environ)
        #
        print "IP displayRaster"
###################################################################
if __name__ == "__main__":
    #
    ip = IpodlasProcess()
    ip.displayRaster("upperEngadine_raster")
    #
    reactor.run()






More information about the Twisted-Python mailing list