(...catching up on this thread...)<div><br></div><div><div class="gmail_quote">On Mon, Feb 21, 2011 at 6:21 AM, Jason Heeris <span dir="ltr">&lt;<a href="mailto:jason.heeris@gmail.com" target="_blank">jason.heeris@gmail.com</a>&gt;</span> wrote:<br>


<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div>There&#39;s a connectionMade event when you do SerialPort(protocol, ...).</div>
There&#39;s no connectionLost event, even if you do that over and over<br>
again.<br></blockquote><div><br></div><div>As Jean-Paul noted, that&#39;s a genuine bug with Twisted.  However, since Twisted is pure python, you can likely override the SerialPort class and make user-land changes to fix the issue.  Maybe you&#39;d even be able to help review or fix the bug? :)  See the following link for guidelines:</div>

<div><br></div><div><a href="http://twistedmatrix.com/trac/wiki/TwistedDevelopment" target="_blank">http://twistedmatrix.com/trac/wiki/TwistedDevelopment</a></div>
<div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div>Should I? I don&#39;t know. My problem is, as a newbie, I *just don&#39;t</div>
know* what the usual way to approach a problem like this is. Or if<br>
there is one.<br></blockquote><div><br></div><div>IIUC, SerialPort doesn&#39;t work with the twisted factory infrastructure.  Factories are used to persist data across different connections.  With SerialPort, there&#39;s just one connection.  Any data you want to store (e.g. a Deferred) should go in your protocol.  </div>


<div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">So, please help me think this through... let&#39;s say I have this<br>
long-lasting protocol. It needs to keep a DeferredLock, so it doesn&#39;t<br>
try to send one message before it&#39;s received the reply for another —<br>
right? It should have a method for sending a command that returns a<br>
Deferred, that will eventually fire with the response (parsed and<br>
converted as necessary, that bit&#39;s easy). The bit I have trouble with<br>
is that the *origin* of the Deferred callback or errback is the<br>
&quot;lineReceived&quot; method — somehow this method needs to know which<br>
Deferred to callback with the response. But how?<br></blockquote><div><br></div><div>Sounds like you just need a queue of pending commands and a state object for the currently executing command.  When runCommand() is called, add the command to the pending queue.  If no command is running, pop the first command in the queue and send it.  When you get a response, the state object tells you what Deferred to fire.  Again, if there&#39;s a pending command, send it.  Sketch:</div>

<div><br></div><div>def _runNext(self):</div><div><div>    if len(self.queue) &gt; 0 and self.state == &#39;IDLE&#39;:</div><div>        self.state = &#39;PROCESSING&#39;</div><div>        self.currentCmd, self.currentDeferred = self.queue.pop()</div>

<div>        self.sendLine(self.constructMessage(self.currentCmd))</div></div><div>def runCommand(self, command, callback):</div><div>    ret = Deferred()</div><div>    self.queue.append((command, ret))</div><div>    self._runNext(self)</div>

<div>    return ret</div><div>def lineReceived(self, line):</div><meta http-equiv="content-type" content="text/html; charset=utf-8"><div>    self.state = &#39;IDLE&#39;</div><div>    try:</div><div>        result = self.parseResponse(self.currentCmd, line)</div>
<div>        self.currentDeferred.callback(result)</div><div>    except Exception, err:</div>
<div>        self.currentDeferred.errback(err)</div><div>    self._runNext(self)</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
PS. Twisted has great documentation for its individual components, but<br>
as soon as you get into anything that doesn&#39;t centre around<br>
&quot;reactor.connectTCP&quot;, it seems like you&#39;re in the dark. All of the<br>
examples and tutorials seem to have near-trivial, completely<br>
synchronous protocols, requiring no back-and-forth or error handling.<br>
Ultimately I&#39;d like to take all of this advice, have an epiphany,<br>
finish my project, bundle my new-found wisdom up into a neat little<br>
package of things I think would make serial comms a happier experience<br>
for all, and publish it somewhere. And maybe write about how to use<br>
Twisted for non-internetty things. But I do need to actually<br>
accomplish something first.</blockquote><div><br></div><div>In case you haven&#39;t yet, see:</div><div><br></div><div> <a href="http://twistedmatrix.com/pipermail/twisted-python/2011-January/023362.html">http://twistedmatrix.com/pipermail/twisted-python/2011-January/023362.html</a></div>
<div><br></div><div>and follow-up threads.</div><div><br>Cheers,</div><div><br>Jason</div></div><br>-- <br>Jason Rennie<br>Research Scientist, ITA Software<br>617-714-2645<br><a href="http://www.itasoftware.com/" target="_blank">http://www.itasoftware.com/</a><br>
<br>
</div>