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()