[kupfer: 13/27] backgroundtask: Introduce background_loader decorator in helplib
- From: Ulrik Sverdrup <usverdrup src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [kupfer: 13/27] backgroundtask: Introduce background_loader decorator in helplib
- Date: Tue, 16 Feb 2010 20:48:13 +0000 (UTC)
commit db443f7983d91bc1304d85b9adb71c206a149a1f
Author: Karol BÄ?dkowski <karol bedkowsk+gh gmail com>
Date: Tue Feb 9 22:40:18 2010 +0100
backgroundtask: Introduce background_loader decorator in helplib
kupfer/obj/helplib.py | 68 +++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 68 insertions(+), 0 deletions(-)
---
diff --git a/kupfer/obj/helplib.py b/kupfer/obj/helplib.py
index 992b2af..d00b69d 100644
--- a/kupfer/obj/helplib.py
+++ b/kupfer/obj/helplib.py
@@ -5,8 +5,13 @@ This module is a part of the program Kupfer, see the main program file for
more information.
"""
+import functools
+import traceback
+
import gio
+from kupfer import task
+
class PicklingHelperMixin (object):
""" This pickling helper will define __getstate__/__setstate__
acting simply on the class dictionary; it is up to the inheriting
@@ -119,3 +124,66 @@ def reverse_action(action, rank=0):
return None
ReverseAction.__name__ = "Reverse" + action.__name__
return ReverseAction
+
+
+def background_loader(interval, delay=5, name=None, update_empty=False):
+ """ Run decorated function in background and cache it result.
+
+ @interval: time between runs function in seconds
+ @delay: optional delay to run background process in second
+ @name: optional name of the thread (for logging)
+ @update_empty: when function return empty result we may decide is cached
+ result should be updated or not. When update_empty==True result always
+ is stored.
+
+ Example:
+ @background_loader(interval=600)
+ def load():
+ return list(<items>)
+
+ Background process should be started by:
+ load.bind_and_start(<optional callback>))
+ - callback is launched after each update
+ or:
+ load.start()
+
+ If cache should be initially filled this may be done with:
+ load.fill_cache(<value>)
+
+ To force run background job call:
+ load.activate()
+ """
+ return functools.partial(_BackgroundLoader, interval=interval,
+ delay=delay, name=name, update_empty=update_empty)
+
+class _BackgroundLoader (object):
+ def __init__(self, func, **kwargs):
+ self.cache = []
+ self.update_empty = kwargs.pop("update_empty", False)
+ self.job = task.BackgroundTaskRunner(func, **kwargs)
+ self.new_data_callback = None
+ self.job.result_callback = self._result_callback
+ self.job.error_callback = self._error_callback
+
+ def _result_callback(self, data):
+ if data or self.update_empty:
+ self.cache[:] = data
+ if self.new_data_callback:
+ self.new_data_callback()
+
+ def _error_callback(self, exc_info):
+ traceback.print_exception(*exc_info)
+
+ def fill_cache(self, data):
+ if data:
+ self.cache[:] = data
+
+ def bind_and_start(self, callback):
+ self.new_data_callback = callback
+ self.job.start()
+
+ def activate(self):
+ self.job.activate()
+
+ def __call__(self):
+ return iter(self.cache)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]