[issue12498] asyncore.dispatcher_with_send, disconnection problem + miss-conception
New submission from François-Xavier Bourlet : Actually the class asyncore.dispatcher_with_send do not handle properly disconnection. When the endpoint shutdown his sending part of the socket, but keep the socket open in reading, the current implementation of dispatcher_with_send will close the socket without sending pending data. Adding this method to the class fix the problem: def handle_close(self): if not self.writable(): dispatcher.close() Note also that this class try to initiate a send even if the socket is maybe not ready for writing: Here's a simple fix: def send(self, data): if self.debug: self.log_info('sending %s' % repr(data)) self.out_buffer = self.out_buffer + data - self.initiate_send() Last but not last, the buffer size of each socket send are way to small (512, a third of an usual TCP frame). Here's the code with a bumped value: def initiate_send(self): num_sent = 0 - num_sent = dispatcher.send(self, self.out_buffer[:512]) + num_sent = dispatcher.send(self, self.out_buffer[:8192]) self.out_buffer = self.out_buffer[num_sent:] Thanks for reading, -- components: IO messages: 139821 nosy: François-Xavier.Bourlet priority: normal severity: normal status: open title: asyncore.dispatcher_with_send, disconnection problem + miss-conception versions: Python 2.7 ___ Python tracker <http://bugs.python.org/issue12498> ___ ___ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue12498] asyncore.dispatcher_with_send, disconnection problem + miss-conception
François-Xavier Bourlet added the comment: I am currently busy, but i will try to allocate some time to propose a path soon. Cheers, 2011/7/24 Charles-François Natali : > > Charles-François Natali added the comment: > > Hello, > >> Actually the class asyncore.dispatcher_with_send do not handle properly >> disconnection. When the endpoint shutdown his sending part of the socket, >> but keep the socket open in reading, the current implementation of >> dispatcher_with_send will close the socket without sending pending data. > > Yes, that's a common problem with "naive" networking code. > >> Note also that this class try to initiate a send even if the socket is maybe >> not ready for writing: >> >> Here's a simple fix: >> def send(self, data): >> if self.debug: >> self.log_info('sending %s' % repr(data)) >> self.out_buffer = self.out_buffer + data >> - self.initiate_send() >> > > Hum, I'm not sure about this. > dispatcher is just a thin wrapper around the underlying socket, so the > semantic of `send` should be the same as `socket.send`, i.e. just call > the send(2) syscall. I think it's the application's reponsibility to > check that the socket is indeed writable, and to cope with potential > failures (e.g. EAGAIN or ENOTCONN). > >> Last but not last, the buffer size of each socket send are way to small >> (512, a third of an usual TCP frame). Here's the code with a bumped value: > > Indeed, 1/3 of the ethernet MTU is quite small. > > Would you like to submit a patch? > > -- > nosy: +neologix > > ___ > Python tracker > <http://bugs.python.org/issue12498> > ___ > -- ___ Python tracker <http://bugs.python.org/issue12498> ___ ___ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue12498] asyncore.dispatcher_with_send, disconnection problem + miss-conception
François-Xavier Bourlet added the comment: No worries, I am glad to see asyncore going away. It was indeed badly designed in the first place. -- François-Xavier Bourlet On Fri, Jun 27, 2014 at 2:28 PM, STINNER Victor wrote: > > STINNER Victor added the comment: > > "Actually the class asyncore.dispatcher_with_send do not handle properly > disconnection. When the endpoint shutdown his sending part of the socket, but > keep the socket open in reading, the current implementation of > dispatcher_with_send will close the socket without sending pending data." > > It looks like asyncore doesn't handle this use case. > > To me, it doesn't look like a minor issue, but more a design issue. Fixing it > requires to change the design of asyncore. > > The asyncio module has a better design. It has a write_eof() method to close > the write end without touching the read end. For example, for sockets, > write_eof() calls sock.shutdown(socket.SHUT_WR). After write_eof(), the read > continues in background as any other task. For the read end, the protocol has > a eof_received() method to decide if the socket should close, or if it should > be kept open for writing (but only for writing). > > Giampaolo wrote: >> I think this thread is becoming a little messy and since asyncore/asynchat >> are in a situation where even the slightest change can break existent code I >> recommend to be really careful. > > Moreover, the asyncore module has been deprecated in favor of the asyncio > module. > > I close this issue for all these reasons. > > Sorry Xavier for your patches, but it's time to focus our efforts on a single > module and asyncio has a much better design to handle such use cases. > > -- > nosy: +haypo > resolution: -> wont fix > status: open -> closed > > ___ > Python tracker > <http://bugs.python.org/issue12498> > ___ -- ___ Python tracker <http://bugs.python.org/issue12498> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com