Author: dmeyer
Date: Fri Jan 18 09:15:08 2008
New Revision: 2976

Log:
o Add new kaa notifier class BackgroundTask
o Rename ThreadCallback to NamedThreadCallback and make it
  a Callback and a BackgroundTask. Replace register with
  a __call__ function that returns InProgress


Modified:
   trunk/base/API_CHANGES.txt
   trunk/base/src/notifier/__init__.py
   trunk/base/src/notifier/async.py
   trunk/base/src/notifier/jobserver.py
   trunk/base/test/jobserver.py

Modified: trunk/base/API_CHANGES.txt
==============================================================================
--- trunk/base/API_CHANGES.txt  (original)
+++ trunk/base/API_CHANGES.txt  Fri Jan 18 09:15:08 2008
@@ -15,3 +15,11 @@
 
    Note: Exception for this is kaa.notifier.url right now
 
+3. Renamed ThreadCallback to NamedThreadCallback and make the first
+   paramater in __init__ the thread information (name or list of name
+   and priority). The register function will be changed to __call__.
+   The NamedThreadCallback is not InProgress object anymore, it is a
+   Callback. In most cases ThreadCallback was not used directly so
+   this API change should not break some code.
+
+

Modified: trunk/base/src/notifier/__init__.py
==============================================================================
--- trunk/base/src/notifier/__init__.py (original)
+++ trunk/base/src/notifier/__init__.py Fri Jan 18 09:15:08 2008
@@ -37,8 +37,8 @@
 from sockets import SocketDispatcher, WeakSocketDispatcher, Socket, IO_READ, 
IO_WRITE
 from event import Event, EventHandler, WeakEventHandler
 from yieldfunc import YieldContinue, YieldCallback, YieldFunction, 
yield_execution
-from jobserver import ThreadCallback, execute_in_thread
-from async import InProgress
+from jobserver import NamedThreadCallback, execute_in_thread
+from async import InProgress, BackgroundTask
 from decorators import execute_in_timer, execute_in_mainloop
 
 # Here's what will be imported into the kaa namespace.
@@ -47,7 +47,8 @@
     'Thread', 'Timer', 'WeakTimer', 'OneShotTimer', 'WeakOneShotTimer', 
'AtTimer',
     'OneShotAtTimer', 'SocketDispatcher', 'WeakSocketDispatcher', 'Socket',
     'IO_READ', 'IO_WRITE', 'Event', 'EventHandler', 'WeakEventHandler',
-    'YieldContinue', 'YieldCallback', 'YieldFunction', 'ThreadCallback', 
'InProgress',
+    'YieldContinue', 'YieldCallback', 'YieldFunction', 'NamedThreadCallback',
+    'InProgress', 'BackgroundTask',
 
     # decorator for sub modules
     # FIXME: while we are breaking the API right now, do we want to keep

Modified: trunk/base/src/notifier/async.py
==============================================================================
--- trunk/base/src/notifier/async.py    (original)
+++ trunk/base/src/notifier/async.py    Fri Jan 18 09:15:08 2008
@@ -29,7 +29,7 @@
 #
 # -----------------------------------------------------------------------------
 
-__all__ = [ 'InProgress' ]
+__all__ = [ 'InProgress', 'BackgroundTask' ]
 
 # python imports
 import logging
@@ -200,3 +200,32 @@
         will be emited only once.
         """
         return Signal._connect(self, callback, args, kwargs, True, weak, pos)
+
+
+class BackgroundTask(object):
+    """
+    Task running in the background. This objects provides a 'completed' and
+    an 'exception' signal and a decorator to create an InProgress object.
+    """
+    def __init__(self):
+        self.signals = {
+            'completed': Signal(),
+            'exception': Signal()
+        }
+
+    def start_background_task():
+        def decorator(func):
+            def newfunc(self, *args, **kwargs):
+                async = InProgress()
+                self.signals['completed'].connect_weak_once(async.finished)
+                self.signals['exception'].connect_weak_once(async.exception)
+                func(self, *args, **kwargs)
+                return async
+            try:
+                newfunc.func_name = func.func_name
+            except TypeError:
+                pass
+            return newfunc
+        return decorator
+    
+    start_background_task = staticmethod(start_background_task)

Modified: trunk/base/src/notifier/jobserver.py
==============================================================================
--- trunk/base/src/notifier/jobserver.py        (original)
+++ trunk/base/src/notifier/jobserver.py        Fri Jan 18 09:15:08 2008
@@ -29,7 +29,7 @@
 #
 # -----------------------------------------------------------------------------
 
-__all__ = [ 'execute_in_thread', 'ThreadCallback' ]
+__all__ = [ 'execute_in_thread', 'NamedThreadCallback' ]
 
 
 # python imports
@@ -39,7 +39,7 @@
 
 # kaa notifier imports
 from callback import Signal, Callback
-from async import InProgress
+from async import InProgress, BackgroundTask
 from thread import MainThreadCallback
 import thread
 
@@ -59,9 +59,7 @@
 
         def newfunc(*args, **kwargs):
             if name:
-                t = ThreadCallback(func, *args, **kwargs)
-                t.register(name, priority)
-                return t
+                return NamedThreadCallback((name, priority), func, *args, 
**kwargs)()
             t = thread.Thread(func, *args, **kwargs)
             t.wait_on_exit(False)
             return t.start()
@@ -75,16 +73,20 @@
     return decorator
 
 
-class ThreadCallback(InProgress):
+class NamedThreadCallback(BackgroundTask, Callback):
     """
     A callback to run a function in a thread. This class is used by
     execute_in_thread, but it is also possible to use this call directly.
     The class inherits from InProgress and will call the connected functions
     on termination or exception.
     """
-    def __init__(self, function, *args, **kwargs):
-        super(ThreadCallback, self).__init__()
-        self._callback = Callback(function, *args, **kwargs)
+    def __init__(self, thread_information, func, *args, **kwargs):
+        Callback.__init__(self, func, *args, **kwargs)
+        BackgroundTask.__init__(self)
+        self.priority = 0
+        if isinstance(thread_information, (list, tuple)):
+            thread_information, self.priority = thread_information
+        self._thread_name = thread_information
         self._server = None
 
 
@@ -95,16 +97,18 @@
         return self._server != None
 
 
-    def register(self, name, priority=0):
+    @BackgroundTask.start_background_task()
+    def __call__(self, *args, **kwargs):
         """
-        Register callback to a thread with the given name.
+        Schedule the callback function on the server, returns an InProgress
+        object.
         """
         if self._server:
-            return
-        self.priority = priority
-        if not _threads.has_key(name):
-            _threads[name] = _Thread(name)
-        self._server = _threads[name]
+            raise RuntimeError('NamedThreadCallback already scheduled')
+        if not _threads.has_key(self._thread_name):
+            _threads[self._thread_name] = _Thread(self._thread_name)
+        self._named_thread_args = args, kwargs
+        self._server = _threads[self._thread_name]
         self._server.add(self)
 
 
@@ -115,11 +119,12 @@
         if self.active():
             self._server.remove(self)
             self._server = None
+            self._named_thread_args = None
 
 
 class _Thread(threading.Thread):
     """
-    Thread processing ThreadCallback jobs.
+    Thread processing NamedThreadCallback jobs.
     """
     def __init__(self, name):
         log.debug('start jobserver %s' % name)
@@ -144,7 +149,7 @@
 
     def add(self, job):
         """
-        Add a ThreadCallback to the thread.
+        Add a NamedThreadCallback to the thread.
         """
         self.condition.acquire()
         self.jobs.append(job)
@@ -155,7 +160,7 @@
 
     def remove(self, job):
         """
-        Remove a ThreadCallback from the schedule.
+        Remove a NamedThreadCallback from the schedule.
         """
         if job in self.jobs:
             self.condition.acquire()
@@ -181,10 +186,13 @@
             # process the job
             job._server = None
             try:
-                MainThreadCallback(job.finished, job._callback())()
+                args, kwargs = job._named_thread_args
+                job._named_thread_args = None
+                r = Callback.__call__(job, *args, **kwargs)
+                MainThreadCallback(job.signals['completed'].emit, r)()
             except Exception, e:
                 e._exc_info = sys.exc_info()
-                MainThreadCallback(job.exception, e)()
+                MainThreadCallback(job.signals['exception'].emit, e)()
         # server stopped
         log.debug('stop thread %s' % self.name)
 

Modified: trunk/base/test/jobserver.py
==============================================================================
--- trunk/base/test/jobserver.py        (original)
+++ trunk/base/test/jobserver.py        Fri Jan 18 09:15:08 2008
@@ -1,7 +1,8 @@
 import time
 import logging
 
-from kaa import ThreadCallback, loop
+import kaa
+from kaa import NamedThreadCallback
 
 def foo(i):
     time.sleep(0.1)
@@ -15,12 +16,12 @@
 logger.addHandler(handler)
 logger.setLevel(logging.DEBUG)
 
-ThreadCallback(foo, 1).register('x')
-ThreadCallback(foo, 2).register('x')
-ThreadCallback(foo, 3).register('x', 5)
-j = ThreadCallback(foo, 4)
-j.register('x')
-ThreadCallback(foo, 5).register('x')
-ThreadCallback(foo, 6).register('y')
-j.unregister()
-loop()
+NamedThreadCallback('x', foo, 1)()
+NamedThreadCallback('x', foo, 2)()
+NamedThreadCallback(('x', 5), foo, 3)()
+j = NamedThreadCallback('x', foo, 4)
+j()
+NamedThreadCallback('x', foo, 5)()
+NamedThreadCallback('y', foo, 6)()
+j.stop()
+kaa.main.run()

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Freevo-cvslog mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/freevo-cvslog

Reply via email to