exvito here
2016-12-15 17:07:42 UTC
Dear all,
The subject says most of it. While diagnosing a behavior on a somewhat
large codebase, I found out something somewhat surprising -- see
subject -- which is replicated with the minimal code example below.
It is a LineReceiver client that:
1. Connects to 127.0.0.1:10000.
2. Sends a line of text.
3. Disconnects one second later.
4. Tries to send another line of text, one second after disconnection.
I expected step 4 to fail somehow, given that Twisted promptly
detected that the connection closed and IProtocol.connectionLost was
called, as documented. Nevertheless, it does not fail.
So the questions are:
a) Why does it not fail? I'm sure there is a good reason for that, as
most things do in Twisted.
b) Does a protocol implementation, like the one in the example, really
need to track connectionMade / connectionLost calls before going for
self.transport.write?
c) Can a protocol implementation, instead, depend on
self.transport.connected for which I found no documentation? (I
probably missed it, where is it?)
Thanks in advance for enlightening me. :-)
Regards,
--
exvito
# --[ cut here ]----------------------------------------------------
from twisted.internet import protocol, reactor, defer
from twisted.protocols import basic
class ClientAPI(basic.LineReceiver):
def _log(self, msg):
print('[connected=%r] %s' % (self.transport.connected, msg))
def _send(self, line):
self.sendLine(line)
self._log('sent: %r' % (line,))
def connectionMade(self):
self._log('connection made')
self._send('first line')
reactor.callLater(1, lambda: self.transport.loseConnection())
def connectionLost(self, reason):
self._log('connection lost')
reactor.callLater(1, self.postConnectionLostCall)
def postConnectionLostCall(self):
self._send('post conn lost call - SHOULD FAIL')
class ClientFactory(protocol.ClientFactory):
protocol = ClientAPI
def clientConnectionFailed(self, connector, reason):
print 'connection failed -', reason
reactor.stop()
if __name__ == '__main__':
factory = ClientFactory()
reactor.connectTCP('127.0.0.1', 10000, factory)
reactor.run()
The subject says most of it. While diagnosing a behavior on a somewhat
large codebase, I found out something somewhat surprising -- see
subject -- which is replicated with the minimal code example below.
It is a LineReceiver client that:
1. Connects to 127.0.0.1:10000.
2. Sends a line of text.
3. Disconnects one second later.
4. Tries to send another line of text, one second after disconnection.
I expected step 4 to fail somehow, given that Twisted promptly
detected that the connection closed and IProtocol.connectionLost was
called, as documented. Nevertheless, it does not fail.
So the questions are:
a) Why does it not fail? I'm sure there is a good reason for that, as
most things do in Twisted.
b) Does a protocol implementation, like the one in the example, really
need to track connectionMade / connectionLost calls before going for
self.transport.write?
c) Can a protocol implementation, instead, depend on
self.transport.connected for which I found no documentation? (I
probably missed it, where is it?)
Thanks in advance for enlightening me. :-)
Regards,
--
exvito
# --[ cut here ]----------------------------------------------------
from twisted.internet import protocol, reactor, defer
from twisted.protocols import basic
class ClientAPI(basic.LineReceiver):
def _log(self, msg):
print('[connected=%r] %s' % (self.transport.connected, msg))
def _send(self, line):
self.sendLine(line)
self._log('sent: %r' % (line,))
def connectionMade(self):
self._log('connection made')
self._send('first line')
reactor.callLater(1, lambda: self.transport.loseConnection())
def connectionLost(self, reason):
self._log('connection lost')
reactor.callLater(1, self.postConnectionLostCall)
def postConnectionLostCall(self):
self._send('post conn lost call - SHOULD FAIL')
class ClientFactory(protocol.ClientFactory):
protocol = ClientAPI
def clientConnectionFailed(self, connector, reason):
print 'connection failed -', reason
reactor.stop()
if __name__ == '__main__':
factory = ClientFactory()
reactor.connectTCP('127.0.0.1', 10000, factory)
reactor.run()