asyncore based port splitter code questions

George Trojan george.trojan at noaa.gov
Fri Jan 8 18:58:51 EST 2010


Thanks for your help. Some comments below.

George

Giampaolo Rodola' wrote:

> On 4 Gen, 18:58, George Trojan <george.tro... at noaa.gov> wrote:
> 
> 
> Secondly, to temporarily "sleep" your connections *don't* remove
> anything from your map.
> The correct way of doing things here is to override readable() and
> writable() methods and make them return False as long as you want your
> connection to hang.
> 
Good advice.

> Now I'm going to comment some parts of your code.
> 
>> class Reader(asyncore.dispatcher):
>>      def __init__(self, sock, writers):
>>          asyncore.dispatcher.__init__(self, sock)
>>          self.writers = writers
>>
>>      def handle_read(self):
>>          data = self.recv(1024)
>>          for writer in self.writers:
>>              writer.add_data(data)
> [...]
>>      def handle_write(self):
>>          while self.data:
>>              log_msg('sending data to %s' % str(self.address))
>>              sent = self.send(self.data)
>>              self.data = self.data[sent:]
>>          self.suspend_channel()
> 
> 
> By looking at how you are appending data you want to send in a buffer,
> it looks like you might want to use asynchat.async_chat rather than
> asyncore.dispatcher.
> async_chat.push() and async_chat.push_with_producer() methods already
> take care of buffers logic and make sure that all the data gets sent
> to the other peer without going lost.
> 
> Actually there's no reason to use asyncore.dispatcher class directly
> except for creating a socket which listens on an interface and then
> passes the connection to another class inheriting from
> asynchat.async_chat which will actually handle that session.

My understanding is that asynchat is used for bi-directional connection, 
I don't see how it applies to my case (forwarding data). However I 
rewrote the Writer class following some of asynchat code.
> 
> So my recommendation is to use asynchat.async_chat whenever possible.

> You really don't want to use time.sleep() there.
> It blocks everything.
> 
>>          while True:
>>              try:
>>                  disp = Dispatcher(port, destinations)
>>                 asyncore.loop(timeout=TMOUT, use_poll=True)
>>              except socket.error, (errno, e):
>>                  if errno == 98:
>>                      log_msg('sleeping %d s: %s', (30, e))
>>                      time.sleep(30)
> 
> Same as above.
> 
I wanted to reconnect after the os cleans up half-closed sockets. 
Otherwise the program exits immediately with a message:
terminating - uncaught exception: [Errno 98] Address already in use

> 
> As a final note I would recommend to take a look at pyftpdlib code
> which uses asyncore/asynchat as part of its core:
> http://code.google.com/p/pyftpdlib
> It can be of some help to figure out how things should be done.
> 
Thanks for good example to study.
> 
> 
> --- Giampaolo
> http://code.google.com/p/pyftpdlib/



More information about the Python-list mailing list