<div dir="ltr"><div>Summary: I am having an issue writing data from an object based on twisted's LineReceiver. Calling self.transport.write from the protocol, some data makes it through, some does not. Using tcpdump, I am not seeing the missing data cross the network interface. </div><div><br></div><div>Ubuntu LTS 14.04</div><div>Python 2.7.6</div><div>Twisted 15.0.0</div><div><br></div><div>The app recieves a bunch of messages from various upstream servers (not mine) and either discards—or bends, folds, spindles and muilates and sends the modified message to a downstream server. The message format is text-based, proprietary and not mine. </div><div><br></div><div>The way it works:</div><div><br></div><div>1. The app puts messages, consisting of a tuple of two strings: an id and the message data, on a queue. The queue is actually a deque on the factory. </div><div>2. There's one client protocol instance for sending, it holds a connection to downstream server. The factory is a reconnecting one, but only if the connection drops. (I'm not creating a new protocol instance/connection per message)</div><div>3. There's a method on the protocol that checks for messages in the factory's queue, and sends them, one at a time. It waits for a short ack text message back from the receiving end, or times out (my app's timeout, not a network stack one) before sending the next message, if any. Code for the sending piece is below.</div><div>4. The downstream end (an app not under my control) is not getting all the messages. If my timeout check runs, and there's not been a returned ack message yet, invariably the sysadmins for the downstream system report they never got that message.</div><div><br></div><div>def check_for_send(self):</div><div>    if not self.in_send_message:</div><div>        try:</div><div>            self.in_send_message = True</div><div>            msg = self.factory.queue.popleft()</div><div>            try:</div><div>                self.waiting_id = msg[0]</div><div>                log.msg("Sending Message: {0}".format(msg[0]))</div><div>                raw_msg = "".join([self.MSG_START, msg[1], self.MSG_END, self.delimiter])</div><div>                threads.deferToThread(self._dump_raw_message, msg[0], raw_msg)</div><div>                self.transport.write(raw_msg)</div><div>                reactor.callLater(30, self.check_for_timeout, msg[0])</div><div>            except:</div><div>                log.msg("Error sending Message: {0}".format(msg[0]))</div><div>                log.err()</div><div>                self.factory.add_message(msg)</div><div>                self.waiting_id = ""</div><div>                self.in_send_message = False</div><div>        except IndexError:</div><div>            self.in_send_message = False</div><div>        finally:</div><div>            reactor.callLater(0, self.check_for_send)</div><div>    else:</div><div>        reactor.callLater(1, self.check_for_send)</div><div><br></div><div>Mostly looking for some advice on further debugging this, as whenever I've called self.transport.write on a lineReceiver over tcp before, it "just worked."</div><div><br></div><div>Observations.</div><div><br></div><div>1. The event loop doesn't appear to be getting stuck. Messages that don't arrive downstream are interleaved with those that do. And the other part of the app that is receiving messages from upstream keeps right on trucking.</div><div><br></div><div>2. I am now writing copies of the messages to disk, that call is right before the transport.write call, and all the "missing" messages do end up on disk.</div><div><br></div><div>3. I also fire the callLater for the timeout function on each message. The disk write and the callLater both happen for missing messages.</div><div><br></div><div>4. I ran tcpdump on the interface for about 30 minutes and matched up with log statements. If I see my protocol timed out waiting for an ack message in my app's log, I can't find the outgoing message on the interface. </div><div><br></div><div>5. I am not seeing any errors in my logs.</div></div>