<html>
<head>
<meta http-equiv=Content-Type content="text/html; charset=iso-8859-1">
<meta name=Generator content="Microsoft Word 10 (filtered)">
<style>
<!--
/* Font Definitions */
@font-face
        {font-family:"MS Mincho";
        panose-1:2 2 6 9 4 2 5 8 3 4;}
@font-face
        {font-family:Tahoma;
        panose-1:2 11 6 4 3 5 4 4 2 4;}
@font-face
        {font-family:"\@MS Mincho";}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        margin-bottom:.0001pt;
        font-size:12.0pt;
        font-family:"Times New Roman";}
a:link, span.MsoHyperlink
        {color:blue;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {color:navy;
        text-decoration:underline;}
span.emailstyle17
        {font-family:Arial;
        color:windowtext;}
span.emailstyle18
        {font-family:Arial;
        color:navy;}
span.EmailStyle19
        {font-family:Arial;
        color:navy;}
@page Section1
        {size:8.5in 11.0in;
        margin:1.0in 1.25in 1.0in 1.25in;}
div.Section1
        {page:Section1;}
-->
</style>
</head>
<body lang=EN-US link=blue vlink=navy>
<div class=Section1>
<p class=MsoNormal><font size=2 color=navy face=Arial><span style='font-size:
10.0pt;font-family:Arial;color:navy'>I’m not trying to bump my question,
but if someone could tell me if I’m just being stupid and missing
something with this code or that it isn’t possible to do what I need with
a spawned process? If I know it isn’t possible, I can just continue down
the path I am. It’s not too much of a pain, but it just feels...wrong.</span></font></p>
<p class=MsoNormal><font size=2 color=navy face=Arial><span style='font-size:
10.0pt;font-family:Arial;color:navy'> </span></font></p>
<p class=MsoNormal><font size=2 color=navy face=Arial><span style='font-size:
10.0pt;font-family:Arial;color:navy'>Thanks,</span></font></p>
<p class=MsoNormal><font size=2 color=navy face=Arial><span style='font-size:
10.0pt;font-family:Arial;color:navy'> </span></font></p>
<p class=MsoNormal><font size=2 color=navy face=Arial><span style='font-size:
10.0pt;font-family:Arial;color:navy'>Jon</span></font></p>
<p class=MsoNormal><font size=2 color=navy face=Arial><span style='font-size:
10.0pt;font-family:Arial;color:navy'> </span></font></p>
<p class=MsoNormal style='margin-left:.5in'><font size=2 face=Tahoma><span
style='font-size:10.0pt;font-family:Tahoma'>-----Original Message-----<br>
<b><span style='font-weight:bold'>From:</span></b>
twisted-python-bounces@twistedmatrix.com [mailto:twisted-python-bounces@twistedmatrix.com]
<b><span style='font-weight:bold'>On Behalf Of </span></b>jmbenski<br>
<b><span style='font-weight:bold'>Sent:</span></b> Tuesday, December 06, 2005
7:58 PM<br>
<b><span style='font-weight:bold'>To:</span></b>
twisted-python@twistedmatrix.com<br>
<b><span style='font-weight:bold'>Subject:</span></b> [Twisted-Python] RE:
waiting on transport return</span></font></p>
<p class=MsoNormal style='margin-left:.5in'><font size=3 face="Times New Roman"><span
style='font-size:12.0pt'> </span></font></p>
<p class=MsoNormal style='margin-left:.5in'><font size=2 color=navy face=Arial><span
style='font-size:10.0pt;font-family:Arial;color:navy'>
</span></font><font size=2 face=Arial><span style='font-size:10.0pt;font-family:
Arial'>Ok, I need some help to write some code using deferred’s the way
they were meant, not the way I’ve bastardized them.</span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'> </span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'>My framework…</span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'> </span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'>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.</span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'> </span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'>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?</span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'> </span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'>class
SyncManagerProtocol(protocol.ProcessProtocol):</span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'> def __init__(self
):</span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'>
self.dataStore = ""</span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'>
##queue that holds the commands </span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'>
self.cmdQueue = list()</span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'>
##queue that holds the callback function to call once the call returns</span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'>
self.deferredQueue = list()</span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'>
</span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'> def
outReceived(self, data):</span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'>
</span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'>
if len(self.cmdQueue) > 0:</span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'>
##take the data and shove it into our internal store</span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'>
self.dataStore += data</span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'>
##determine what is good data</span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'>
cmd = self.cmdQueue[0]</span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'>
##look for the command the is next in the queue. grab all the return data</span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'>
##between the command block.</span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'>
## syncCmd {</span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'>
## return data goes here</span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'>
## } syncCmd</span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'>
cmdBlock = r"%s {(?P<cmd>.*)} %s(?P<rest>.*)" % (cmd,
cmd)</span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'>
errBlock = r"invalid {(?P<errMsg>.*)}"</span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'> </span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'>
cmdMatch = re.compile( cmdBlock, re.S ).search( self.dataStore
) </span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'> </span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'>
if cmdMatch:</span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'>
##set the rest of the data to the dataStore. This clears out the current
contents</span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'>
##but keeps any extra data that may be coming in from the next command</span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'>
self.dataStore = cmdMatch.group( "rest" )</span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'>
##clean up this command</span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'>
self.commandComplete( cmdMatch.group("cmd").lstrip() )</span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'> </span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'> ##This is called
if all the data we need has been
returned.
</span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'> def
commandComplete(self, cmdData):</span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'>
##pop this command since we are done with it</span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'>
self.cmdQueue.pop(0)</span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'>
##pop the deferred that matches this command</span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'>
deferred = self.deferredQueue.pop(0) </span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'>
##pass the results to the deferred</span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'>
deferred.callback( cmdData )</span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'> </span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'> ##interface to
the process that sends a command to execute</span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'> def sendCommand( self,
cmd, args, deferred ): </span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'>
##store the command in the queue, so we can check it when we get data</span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'>
self.cmdQueue.append( cmd )</span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'>
##store the deferred in the queue that we need to run when this command has
been completed</span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'>
self.deferredQueue.append( deferred )</span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'>
##write out command to the process</span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'>
cmd = cmd + " " + args + "\n"</span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'>
self.transport.write( cmd )</span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'> </span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'> </span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'> </span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'>## This code is my
client interface class to the server that holds the processProtocol instance.
##</span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'> </span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'> </span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'>#setup a command that will handle
errors or good data</span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'>d = defer.Deferred().addCallback(
self.handleThisCommand )</span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'>#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</span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'>d.addCallback(
self.theRestOfTheCommands )</span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'>cmd = "some command goes
here”</span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'>self.processProtocol.sendCommand(
"syncCmd", cmd, d)</span></font></p>
<p class=MsoNormal style='margin-left:1.0in'><font size=3 face="Times New Roman"><span
style='font-size:12.0pt'> </span></font></p>
</div>
</body>
</html>