[kupfer] core: "Exception Guard" source initialization and first load



commit ede23702ac446ed375814f8449422c2e9a6573ba
Author: Ulrik Sverdrup <ulrik sverdrup gmail com>
Date:   Tue Jan 19 15:57:19 2010 +0100

    core: "Exception Guard" source initialization and first load
    
    We must call SourceController.initialize(..) before commencing program
    operation.
    We use a context manager called _exception_guard to perform methods on
    a source, ousting it from the SourceController's catalog if any
    exception is raised.

 kupfer/core/data.py    |    2 +-
 kupfer/core/sources.py |   41 +++++++++++++++++++++++++----------------
 2 files changed, 26 insertions(+), 17 deletions(-)
---
diff --git a/kupfer/core/data.py b/kupfer/core/data.py
index eac5d46..915b19a 100644
--- a/kupfer/core/data.py
+++ b/kupfer/core/data.py
@@ -477,7 +477,7 @@ class DataController (gobject.GObject, pretty.OutputMixin):
 		other_sources = set(s_s) - direct_sources
 		sc.add(direct_sources, toplevel=True)
 		sc.add(other_sources, toplevel=False)
-		sc.cache_toplevel_sources()
+		sc.initialize()
 		self.source_pane.source_rebase(sc.root)
 		learn.load()
 
diff --git a/kupfer/core/sources.py b/kupfer/core/sources.py
index 9dd8ba1..a608f35 100644
--- a/kupfer/core/sources.py
+++ b/kupfer/core/sources.py
@@ -1,3 +1,6 @@
+from __future__ import with_statement
+
+import contextlib
 import gzip
 import hashlib
 import itertools
@@ -237,7 +240,11 @@ class SourceDataPickler (pretty.OutputMixin):
 		return True
 
 class SourceController (pretty.OutputMixin):
-	"""Control sources; loading, pickling, rescanning"""
+	"""Control sources; loading, pickling, rescanning
+
+	Call .add() to add sources.
+	Call .initialize() before use commences.
+	"""
 	def __init__(self):
 		self.rescanner = PeriodicRescanner(period=3)
 		self.sources = set()
@@ -425,18 +432,11 @@ class SourceController (pretty.OutputMixin):
 				continue
 			sourcepickler.pickle_source(source)
 
-	def _checked_rescan_source(self, source, force=True):
-		"""
-		Rescan @source and check for exceptions, if it
-		raises, we remove it from our source catalog
-		"""
-		# to "rescue the toplevel", we throw out sources that
-		# raise exceptions on rescan
+	@contextlib.contextmanager
+	def _exception_guard(self, source):
+		"Guard for exceptions, ousting @source from catalog if any is raised"
 		try:
-			if force:
-				self.rescanner.register_rescan(source, sync=True)
-			else:
-				source.get_leaves()
+			yield
 		except Exception:
 			import traceback
 			self.output_error("Loading %s raised an exception:" % source)
@@ -446,14 +446,23 @@ class SourceController (pretty.OutputMixin):
 			self.sources.discard(source)
 			self.toplevel_sources.discard(source)
 
-	def cache_toplevel_sources(self):
-		"""Ensure that all toplevel sources are cached"""
+	def initialize(self):
+		"Initialize all sources and cache toplevel sources"
 		for src in set(self.sources):
-			src.initialize()
+			with self._exception_guard(src):
+				src.initialize()
 		for src in set(self.toplevel_sources):
-			self._checked_rescan_source(src, force=False)
+			with self._exception_guard(src):
+				self._rescan_source(src, force=False)
 		self.loaded_successfully = True
 
+	def _rescan_source(self, source, force=True):
+		if force:
+			self.rescanner.register_rescan(source, sync=True)
+		else:
+			source.get_leaves()
+
+
 _source_controller = None
 def GetSourceController():
 	global _source_controller



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]