[Twisted-Python] RE: waiting on transport return

jmbenski at micron.com jmbenski at micron.com
Tue Dec 6 21:58:13 EST 2005

            Ok, I need some help to write some code using deferred's the way they were meant, not the way I've bastardized them.


My framework...


I have a client that will connect to a server and MAINTAIN that connection.  I can't create a protocol factory.  The server and the client communicate commands through stdin and stdout.  I need to write my commands to the server and wait for the response in some cases.


I've setup a system that passes a deferred chain to my process protocol and once my process knows that the data it needs is received it will kick off the deferred chain that happens after that response.  This seems backwards.  From my reading and understanding of deferreds, they should bubble down and not have to be pushed up.  How do I handle the case of some protocol command kicking off the rest of a deferred chain or of passing back a deferred, so that I can add to it the things that need to run?


class SyncManagerProtocol(protocol.ProcessProtocol):

    def __init__(self ):

        self.dataStore = ""

        ##queue that holds the commands 

        self.cmdQueue = list()

        ##queue that holds the callback function to call once the call returns

        self.deferredQueue = list()


    def outReceived(self, data):


        if len(self.cmdQueue) > 0:

            ##take the data and shove it into our internal store

            self.dataStore += data

            ##determine what is good data

            cmd = self.cmdQueue[0]

            ##look for the command the is next in the queue.  grab all the return data

            ##between the command block.

            ##      syncCmd {

            ##      return data goes here

            ##      } syncCmd

            cmdBlock = r"%s {(?P<cmd>.*)} %s(?P<rest>.*)" % (cmd, cmd)

            errBlock = r"invalid {(?P<errMsg>.*)}"


            cmdMatch = re.compile( cmdBlock, re.S ).search( self.dataStore )           


            if cmdMatch:

                ##set the rest of the data to the dataStore.  This clears out the current contents

                ##but keeps any extra data that may be coming in from the next command

                self.dataStore = cmdMatch.group( "rest" )

                ##clean up this command

                self.commandComplete( cmdMatch.group("cmd").lstrip() )


    ##This is called if all the data we need has been returned.                   

    def commandComplete(self, cmdData):

        ##pop this command since we are done with it


        ##pop the deferred that matches this command

        deferred = self.deferredQueue.pop(0)        

        ##pass the results to the deferred

        deferred.callback( cmdData )


    ##interface to the process that sends a command to execute

    def sendCommand( self, cmd, args, deferred ):       

        ##store the command in the queue, so we can check it when we get data

        self.cmdQueue.append( cmd )

        ##store the deferred in the queue that we need to run when this command has been completed

        self.deferredQueue.append( deferred )

        ##write out command to the process

        cmd = cmd + " " + args + "\n"

        self.transport.write( cmd )




##   This code is my client interface class to the server that holds the processProtocol instance.   ##



#setup a command that will handle errors or good data

d = defer.Deferred().addCallback( self.handleThisCommand )

#run the calling function handler that will handle an error or returned data.  This will allow something like a GUI to process data that will now be available

d.addCallback( self.theRestOfTheCommands )

cmd = "some command goes here"

self.processProtocol.sendCommand( "syncCmd", cmd, d)


-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://twistedmatrix.com/pipermail/twisted-python/attachments/20051206/fd900381/attachment.htm 

More information about the Twisted-Python mailing list