Re: [Twisted-Python] ITransport.write after IProtocol.connectionLost -- no failure/exception?

2016-12-16 Thread Cory Benfield

> On 15 Dec 2016, at 12:07, exvito here  wrote:
> 
> 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:1.
> 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.

I can’t speak for the design of Twisted, but this is definitely an intended 
implementation behaviour: because twisted’s write method is non-blocking, it is 
generally nicer to avoid write exploding in your face when disconnected.

> b) Does a protocol implementation, like the one in the example, really
> need to track connectionMade / connectionLost calls before going for
> self.transport.write?

A well-written protocol should stop finding reasons to write once 
connectionLost is called, yes. Similarly, it should probably avoid writing 
before connectionMade.

> c) Can a protocol implementation, instead, depend on
> self.transport.connected for which I found no documentation? (I
> probably missed it, where is it?)

I have no good answer to this one, but basically I suspect the answer is “yes, 
for the default TCP transports”, but “no, not in the general case, because it’s 
not part of a documented interface”.

Cory


___
Twisted-Python mailing list
Twisted-Python@twistedmatrix.com
http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python


Re: [Twisted-Python] ITransport.write after IProtocol.connectionLost -- no failure/exception?

2016-12-16 Thread Glyph Lefkowitz

> On Dec 16, 2016, at 5:22 AM, Cory Benfield  wrote:
> 
> 
>> On 15 Dec 2016, at 12:07, exvito here  wrote:
>> 
>> 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:1.
>> 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.
> 
> I can’t speak for the design of Twisted, but this is definitely an intended 
> implementation behaviour: because twisted’s write method is non-blocking, it 
> is generally nicer to avoid write exploding in your face when disconnected.

I can! The main design feature of this approach is that if you have a loop like 
this:

for x in messages:
self.transport.write(self.encode(x))

you should not have to write it to be:

for x in messages:
if self._flagISetInConnectionLost:
break
self.transport.write(self.encode(x))

just to avoid seeing tracebacks in your logs.

If you care about the disconnection event, implement connectionLost to do the 
thing that needs to be done (in this case, stop your LoopingCall).  That's what 
that callback is there for!

-glyph
___
Twisted-Python mailing list
Twisted-Python@twistedmatrix.com
http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python