[Twisted-Python] spawnProcess help needed
Phil Christensen
phil at bubblehouse.org
Tue Dec 9 13:43:00 MST 2008
Hello All-
I'm running into an issue with a project I'm working on that involves
coordinating a large number of external processes to encode audio into
different formats, and do other bookkeeping.
I seem to be having a problem when I use spawnProcess to call the
md5sum binary. The processes spawned seem to stick around forever,
until I kill the server. This doesn't appear to happen with any other
binary.
I start with the following abstract class:
class DefaultProcessProtocol(protocol.ProcessProtocol):
def __init__(self, preserveOut=True, preserveErr=True):
self.deferred = defer.Deferred()
self.debug = False
self.preserveOut = preserveOut
self.out = ''
self.preserveErr = preserveErr
self.err = ''
def connectionMade(self):
if(self.debug):
print '%s connection made' % self.__class__.__name__
def outReceived(self, data):
if(self.debug):
print '%s stdout: %s' % (self.__class__.__name__, data)
if(self.preserveOut):
self.out += data
def errReceived(self, data):
if(self.debug):
print '%s stderr: %s' % (self.__class__.__name__, data)
if(self.preserveErr):
self.err += data
def processEnded(self, status):
if(isinstance(status.value, error.ProcessDone)):
self.deferred.callback(self)
else:
if(self.out):
print self.out
if(self.err):
print self.err
self.deferred.errback(status.value)
Then I made a subclass as follows:
class MD5Checksum(DefaultProcessProtocol):
@staticmethod
def run(target, md5_path='/usr/bin/md5sum'):
hasher = MD5Checksum(preserveOut=True)
hasher.debug = True
reactor.spawnProcess(hasher, md5_path, [md5_path, target])
return hasher.deferred
def get_checksum(self):
filehash = self.out
if(filehash.find('=') == -1):
filehash = [output.strip() for output in
filehash.split(' ')][0]
else:
filehash = [output.strip() for output in
filehash.split('=')][1]
return filehash
With the plan of executing it inside an inlineCallbacks-decorated
function, like this:
proto = yield process.MD5Checksum.run(filename)
checksum = proto.get_checksum()
Everything is basically working, except for the fact that the md5sum
processes never go away. It does seem that processEnded is being
called, since that's what issues the callback on the deferred returned
by run(), but the process sticks around, as a non-zombie, non-defunct
process that still appears to be using small amounts of CPU time.
Also, once the checksum has been retrieved, killing the server doesn't
cause any errors, unlike when a process is legitimately terminated by
killing the server, which displays an error (since right now i'm not
actually catching ProcessTerminated scenarios):
2008-12-09 15:17:48-0500 [-] Unhandled error in Deferred:
2008-12-09 15:17:48-0500 [-] Unhandled Error
Traceback (most recent call last):
Failure: twisted.internet.error.ProcessTerminated: A process
has ended with a probable
error condition: process ended by signal 2.
Any help in this matter would be appreciated...
-phil
More information about the Twisted-Python
mailing list