473,508 Members | 2,229 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Modification to asyncore.py to support threaded event loop

This is for folks who are familiar with asynchronous event handling in
Python using the asyncore module.

If you have ever used the asyncore module, you will realize that it's
event loop does not have a programmable exit condition. It keeps
looping till the channels in its socket map (a dictionary) are closed
and don't have any pending reads/writes.

If you are using Python threads in your application, by using either
the threading or thread modules, adding asyncore capability on top of
it is a bit tricky. The moment you call asyncore.loop after
initializing your asyncore based client/server, it takes over the main
thread. Hence, if you want to mix threaded classes (derived from
threading.Thread) and asyncore in one program, the only recourse is to
create and initialize all your thread objects first and call
asyncore.loop as the last function in your main thread.

However, with a small hack it is possible to get asyncore event loop
running in its own thread, as shown below.

The following is a mixin class, which derives from threading.Thread
and also overrides asyncore.loop in its 'run()' method.

-================================================== ========================-
import threading

class AsyncoreThread(threading.Thread):
""" Asyncore thread class """

def __init__(self, timeout=30.0, use_poll=0,map=None):
self.flag=True
self.timeout=30.0
self.use_poll=use_poll
self.map=map
threading.Thread.__init__(self, None, None, 'asyncore thread')

def run(self):

self.loop()

def loop(self):

# print 'In AsyncoreThread:loop...'
if self.map is None:
self.map = asyncore.socket_map

if self.use_poll:
if hasattr(select, 'poll'):
poll_fun = asyncore.poll3
else:
poll_fun = asyncore.poll2
else:
# print 'Using asyncore.poll...'
poll_fun=asyncore.poll

while self.map and self.flag:
poll_fun(self.timeout,self.map)

def end(self):
print 'Ending asyncore loop...'
self.flag=False
self.map=None

-================================================== ==========================-
Now you can initialize your asyncore based clients/servers and instead
of calling 'asyncore.loop', do it as follows,

t=AsyncoreThread(timeout=mytimeout,...)
t.start()

Since the 'run()' method of this class calls 'loop()' which is exactly
the same as asyncore.loop, only that it gets the asyncore event
handler running in a separate thread, without monopolizing the main
thread of your Python app.

I have used this model successfully in my program, HarvestMan. I wrote
to Sam Rushing, author of asyncore module and here is what he said.

<QUOTE>
"I would recommend separating out your event loop and sending it to
the
Python folks for possible inclusion in the asyncore module. I had
always intended the loop() function in asyncore.py to be a 'field
replaceable item', and in fact have over the years made many different
versions of it. Though this isn't really talked about in asyncore.py,
it's clear if you look at Medusa, which is where the module came
from."
</QUOTE>

Perhaps this is worth a PEP for inclusion in Python 2.4?

Thanks & Regards

-Anand
Jul 18 '05 #1
3 5246

ab******@gmail.com (Anand Pillai) wrote:

If you have ever used the asyncore module, you will realize that it's
event loop does not have a programmable exit condition. It keeps
looping till the channels in its socket map (a dictionary) are closed
and don't have any pending reads/writes.
With the asyncore that will be included with Python 2.4, loop() has a
'count' argument. Your 'programmable exit condition' is simple...

while not exit_condition_satisfied:
asyncore.loop(count=1)

If you are using Python threads in your application, by using either
the threading or thread modules, adding asyncore capability on top of
it is a bit tricky. The moment you call asyncore.loop after
initializing your asyncore based client/server, it takes over the main
thread. Hence, if you want to mix threaded classes (derived from
threading.Thread) and asyncore in one program, the only recourse is to
create and initialize all your thread objects first and call
asyncore.loop as the last function in your main thread.

However, with a small hack it is possible to get asyncore event loop
running in its own thread, as shown below.
Here's an easier way to get asyncore running in its own thread, with
nearly all the functionality you mention, without having to subclass
Thread.

def asyncore_loop(exit_condition, timeout=30.0,
use_poll=False, map=None):
if map is None:
map = asyncore.map
while map and not exit_condition:
asyncore.loop(timeout=30.0, use_poll=False, map=map, count=1)

exit_condition = []

threading.Thread(target=asyncore_loop, args=(exit_condition,)).start()

#to kill the thread...
exit_condition.append(None)

The following is a mixin class, which derives from threading.Thread
and also overrides asyncore.loop in its 'run()' method.
[snip unnecessary code]
Now you can initialize your asyncore based clients/servers and instead
of calling 'asyncore.loop', do it as follows,
See the snippet I provide above.

Perhaps this is worth a PEP for inclusion in Python 2.4?


Module and/or functionality additions do not require a PEP (from what I
understand). Changing the behavior of the language, adding a builtin,
etc., that requires a PEP.

It is not going to make it into Python 2.4. How would I know this?
Because "no new functionality after the beta". We're on beta 2, and
even small functionality additions that were pre-approved (but not
implemented) are not making it into 2.4.

What about for Python 2.5? I doubt it would be added there either. The
functionality is very simple to implement if you know what you are doing,
and doesn't require copying the internals of asyncore.loop to make it
happen.

- Josiah

Jul 18 '05 #2
I tried your code and this is the result...
Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/lib/python2.3/threading.py", line 436, in __bootstrap
self.run()
File "/usr/lib/python2.3/threading.py", line 416, in run
self.__target(*self.__args, **self.__kwargs)
File "urlserver.py", line 205, in asyncore_loop
map = asyncore.map
AttributeError: 'module' object has no attribute 'map'

asyncore does not have an attribute named 'map', only socket_map.
'map' is an argument to ascynore.loop function, again not its
attribute.

Did you try this code out before posting it here?

Also, asyncore.loop has a while loop inside it, and you are adding
another while loop on top. Clearly your exit condition, if it works is
going to only exit the outer while loop, not the inner one. I dont
think it is going to work.
-Anand

Josiah Carlson <jc******@uci.edu> wrote in message news:<ma**************************************@pyt hon.org>...
ab******@gmail.com (Anand Pillai) wrote:

If you have ever used the asyncore module, you will realize that it's
event loop does not have a programmable exit condition. It keeps
looping till the channels in its socket map (a dictionary) are closed
and don't have any pending reads/writes.


With the asyncore that will be included with Python 2.4, loop() has a
'count' argument. Your 'programmable exit condition' is simple...

while not exit_condition_satisfied:
asyncore.loop(count=1)

If you are using Python threads in your application, by using either
the threading or thread modules, adding asyncore capability on top of
it is a bit tricky. The moment you call asyncore.loop after
initializing your asyncore based client/server, it takes over the main
thread. Hence, if you want to mix threaded classes (derived from
threading.Thread) and asyncore in one program, the only recourse is to
create and initialize all your thread objects first and call
asyncore.loop as the last function in your main thread.

However, with a small hack it is possible to get asyncore event loop
running in its own thread, as shown below.


Here's an easier way to get asyncore running in its own thread, with
nearly all the functionality you mention, without having to subclass
Thread.

def asyncore_loop(exit_condition, timeout=30.0,
use_poll=False, map=None):
if map is None:
map = asyncore.map
while map and not exit_condition:
asyncore.loop(timeout=30.0, use_poll=False, map=map, count=1)

exit_condition = []

threading.Thread(target=asyncore_loop, args=(exit_condition,)).start()

#to kill the thread...
exit_condition.append(None)

The following is a mixin class, which derives from threading.Thread
and also overrides asyncore.loop in its 'run()' method.


[snip unnecessary code]
Now you can initialize your asyncore based clients/servers and instead
of calling 'asyncore.loop', do it as follows,


See the snippet I provide above.

Perhaps this is worth a PEP for inclusion in Python 2.4?


Module and/or functionality additions do not require a PEP (from what I
understand). Changing the behavior of the language, adding a builtin,
etc., that requires a PEP.

It is not going to make it into Python 2.4. How would I know this?
Because "no new functionality after the beta". We're on beta 2, and
even small functionality additions that were pre-approved (but not
implemented) are not making it into 2.4.

What about for Python 2.5? I doubt it would be added there either. The
functionality is very simple to implement if you know what you are doing,
and doesn't require copying the internals of asyncore.loop to make it
happen.

- Josiah

Jul 18 '05 #3

ab******@gmail.com (Anand Pillai) wrote:

I tried your code and this is the result...
[snip exception]
asyncore does not have an attribute named 'map', only socket_map.
'map' is an argument to ascynore.loop function, again not its
attribute.
socket_map then, whatever.

Did you try this code out before posting it here?
No, I typed it out in my email client. But my statement still holds,
the functionality is trivial to implement if you know what you are doing,
and shouldn't be in the asyncore module.

Also, asyncore.loop has a while loop inside it, and you are adding
another while loop on top. Clearly your exit condition, if it works is
going to only exit the outer while loop, not the inner one. I dont
think it is going to work.


If you check the source code for asyncore.py in Python 2.4 (available
from Python CVS), you will discover that you can provide an optional
'count' argument to asyncore.loop. You'll notice that I both mention
it:
With the asyncore that will be included with Python 2.4, loop() has a
'count' argument. Your 'programmable exit condition' is simple...
and use it:
asyncore.loop(timeout=30.0, use_poll=False, map=map, count=1)


In this case, the 'inner loop' only runs for one pass. Certainly in
Python <2.4, it would run without stopping (unless the socket map became
empty), but I was referencing 2.4, not 2.3 or prior.
- Josiah

Jul 18 '05 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
2690
by: Michael Welsh | last post by:
In order to learn sockets in Python I am trying to write a simple group chat server and client. I need a little nudge, please. My question contains some GUI but only as decoration. The root...
5
5925
by: David M. Wilson | last post by:
Hi peeps, I finally got around recently to doing something serious using Python for serving network clients asynchronously, deciding on asyncore as my starting point. After 2 days or so of...
0
1744
by: Tony Meyer | last post by:
Changes in asyncore from 2.3 to 2.4 mean that asyncore.poll() now passes all the sockets in the map to select.select() to be checked for errors, which is probably a good thing. If an error occurs,...
29
2745
by: Frank Millman | last post by:
Hi all I am writing a multi-user accounting/business system. Data is stored in a database (PostgreSQL on Linux, SQL Server on Windows). I have written a Python program to run on the client,...
3
3646
by: Jos | last post by:
Hello. I'm using the asyncore and _chat modules to create a network server. I also have, running in a separate thread(s), a "producer" which needs to "push" data onto the network connection(s)....
1
1787
by: Chris | last post by:
I've implemented a real basic IRC client class in 100 lines using asynchat (yes I know about Twisted). The problem I'm having is arbitrarily starting and stopping multiple instances of this class...
5
7089
by: JamesHoward | last post by:
I have a problem with python's asyncore module throwing a bad file descriptor error. The code might be difficult to copy here, but the problem is essentially: The server wants to sever the...
7
2723
by: billie | last post by:
Hi all. I've just terminated a server application using asyncore / asynchat frameworks. I wrote a test script that performs a lot of connections to the server app and I discovered that asyncore...
8
2614
by: Frank Millman | last post by:
Hi all I have been using my own home-brewed client/server technique for a while, using socket and select. It seems to work ok. The server can handle multiple clients. It does this by creating a...
0
7229
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
7129
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
7333
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
7398
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
5637
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
1
5057
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
3208
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
3194
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
1566
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.