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