[Twisted-Python] process status
Daniel Isenegger
disen at geo.unizh.ch
Tue Aug 2 11:10:39 MDT 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