Here's a patch that adds an AsyncHandler class to handler.py. It also adds support for responding to asynchronous matches in deskbarentry.py. If you are adventurous there's also attached async_test.py - an AsyncHandler to stick in your handlers/ dir. async_test.py also contains a small test suite for AsyncHandler (I might have broken it though ;-P) WHAT IS THIS!? Oh I forgot to mention... AsyncHandler runs query() in a sperate thread. Much more than that infact... Highlights include: - automagically requiry on the fly without creating new threads. - always maximally one thread per instance. - allows for queries to be stopped in an orderly fashion. - allow to return partial results during the query() call - any old handler can be made async by just extending AsyncHandler instead of Handler! What can I say. It's shiny! Try it out. Look at the code. Flame me for all the obvious errors! IMPORTANT: The patch depends on the two patches in my previous mail. Cheers Mikkel
Attachment:
2005-10-11-async_handler.patch
Description: application/drivel
from handler import *
from time import sleep
NAME = "Async Test Module"
EXPORTED_CLASS = "AsyncTestHandler"
class AsyncTestMatch (Match):
def __init__(self, handler, name, icon=None):
Match.__init__ (self, handler, name)
def get_handler(self):
return self._handler
def get_name(self, text=None):
return {"name": self._name}
def get_verb(self):
return "%(name)s - %(text)s"
def action(self, text=None):
pass
class AsyncTestHandler (AsyncHandler):
QUERY_TIME = 6
def __init__ (self):
AsyncHandler.__init__ (self, None)
def query (self, qstring, max=5):
for i in range (self.QUERY_TIME):
sleep (0.5)
print "Querying: " + (i+1)*"."
if i == 3:
self.emit_query_ready ([AsyncTestMatch(self, "partial results - %s"%qstring)])
self.check_query_changed (self.clean_me, [qstring])
return [AsyncTestMatch(self, "returned results - %s"%qstring)]
def clean_me (self, args):
print "Clean up for query: " + str(args)
def stop (self):
pass
def get_priority(self):
return 300
if __name__ == "__main__" :
import sys
from os.path import join, basename, normpath, abspath
from os.path import split, expanduser, exists, isfile, dirname
import gobject
name = join(dirname(__file__), '..')
print 'Changing PYTHONPATH'
sys.path.insert(0, abspath(name))
def res_cb (sender, matches):
print str(type(matches))
for match in matches:
print "got match: %s" % match.get_name ()
gobject.threads_init ()
loop = gobject.MainLoop()
ath = AsyncTestHandler ()
print "subclass: %s < %s : %s" % (ath.__class__,AsyncHandler, issubclass(ath.__class__,AsyncHandler))
sys.exit(0)
ath.connect ("query-ready", res_cb)
ath.query_async ("first query")
gobject.timeout_add (2100, ath.query_async, "another query")
gobject.timeout_add (2200, ath.query_async, "we keep querying!")
gobject.timeout_add (2300, ath.query_async, "again and again and again...")
#gobject.timeout_add (4100, ath.stop_query)
loop.run()