Asyncore Loop Question

Steve Holden steve at holdenweb.com
Tue Nov 1 01:39:30 CET 2005


John W wrote:
> On 10/31/05, Steve Holden <steve at holdenweb.com> wrote:
> 
>>John W wrote:
>>
>>>Hello,
>>>
>>>I have a gui application where I am trying to use the asyncore module to
>>>gather data from other computers. I am able to connect, but I am getting
>>>constant handle_write_event method calls into my application. It is
>>>obviously slowing down the gui processing significantly.
>>>
>>>My understanding is that the handle_write_event and handle_read_event
>>
>>are
>>
>>>both edge notifications and I should just get the method call
>>
>>essentially
>>
>>>just once.
>>>
>>>I think the problem is how I have my loop() call configured. All I am
>>
>>trying
>>
>>>to do with the code below is to open the socket (that works) and then
>>>receive a single handle_write_event method call. Instead, I am getting
>>>constantly barraged with them.
>>>
>>>I have tried several different types of the loop() call (using poll,
>>>timeout...) but with no luck. If anyone can explain what I should be
>>
>>doing
>>
>>>to get a single handle_write_event call until I actually write something
>>
>>to
>>
>>>the socket (which my code is not presently doing yet), I would
>>
>>appreciate
>>
>>>Below is some code showing what I am doing:
>>>
>>>--------------------------------------------------------------
>>>class Connection(asyncore.dispatcher):
>>>def __init__ (self, server_name, port_num ):
>>>self.message_queue = []
>>>
>>>asyncore.dispatcher.__init__(self)
>>>self.create_socket( socket.AF_INET, socket.SOCK_STREAM )
>>>self.connect(( server_name, port_num ))
>>>
>>>
>>>def handle_read_event( self ):
>>>print "handle_read_event received"
>>>
>>>
>>>def handle_write_event( self ):
>>>print "Asking for a write"
>>>
>>>if len( self.message_queue ) > 0:
>>># Pop the first message off the queue
>>>self.send_next_message()
>>>
>>>
>>>class TestApp:
>>>def __init__( self, server_name, port_number ):
>>>
>>>self.nomad = Connection( server_name, port_number )
>>>asyncore.loop()
>>>
>>>
>>>Output ends up being a constant stream of:
>>>Asking for a write
>>>Asking for a write
>>>Asking for a write
>>>Asking for a write
>>>Asking for a write
>>>....
>>>...
>>>...
>>>
>>>
>>
>>Normally if a socket channel asks for a write and you have no data you
>>should respond by removing it from the list of write-enabled channels
>>for the asyncore loop until you *do* have some data for it. Otherwise
>>every time the loop scans the channels expecting notification it will
>>tell you again that you can write to that channel.
>>

> 
> Steve,
> 
> Ar you saying that I should close the connection until I have data to write?
> Or should I be using the readable and writable methods to turn it off?
> 
> Thanks for your help, unfortunatly, I have struggled with the documentation
> and getting a clear understanding of everything. This is my first socket
> program as well.
> 
I was actually mis-remembering my asyncore documentation, which is a 
little sad given that I wrote it :-)

What you need is to implement a writable() method. Suppose your output 
generation creates a buffer is self.buffer, a suitable implementation 
would look like this:

     def writable(self):
         return (len(self.buffer) > 0)

As I wrote in the documentation:

"""
writable( )

Called each time around the asynchronous loop to determine whether a 
channel's socket should be added to the list on which write events can 
occur. The default method simply returns True, indicating that by 
default, all channels will be interested in write events.
"""

regards
  Steve
-- 
Steve Holden       +44 150 684 7255  +1 800 494 3119
Holden Web LLC                     www.holdenweb.com
PyCon TX 2006                  www.python.org/pycon/




More information about the Python-list mailing list