Package Ganga :: Package Core :: Package GangaRepository :: Module GangaRepository
[hide private]
[frames] | no frames]

Source Code for Module Ganga.Core.GangaRepository.GangaRepository

  1  ################################################################################ 
  2  # Ganga Project. http://cern.ch/ganga 
  3  # 
  4  # $Id: GangaRepository.py,v 1.1.2.9 2009-07-16 14:04:17 ebke Exp $ 
  5  ################################################################################ 
  6   
  7  # Only the corresponding registry may access the methods of a GangaRepository. 
  8  # It should only raise RepositoryErrors and LockingErrors 
  9   
 10  # there are two "MAGIC" variables in an object: id and status. 
 11  # If a root object has an id field, it will be set to the repository id 
 12  # if a root object has a status field and some load error occurs, it will be set to "incomplete" 
 13   
 14  import Ganga.Utility.logging 
 15  logger = Ganga.Utility.logging.getLogger() 
 16   
 17  from Ganga.Utility.Plugin import PluginManagerError, allPlugins 
 18  from Ganga.Core.InternalServices.Coordinator import disableInternalServices 
 19  from Ganga.Core import GangaException 
 20   
 21  from Ganga.GPIDev.Base.Objects import GangaObject 
 22  from Ganga.GPIDev.Schema import Schema, Version 
 23   
 24  # Empty Ganga Object. This must never be saved back to file. 
25 -class EmptyGangaObject(GangaObject):
26 """Empty Ganga Object. Is used to construct incomplete jobs""" 27 _schema = Schema(Version(0,0), {}) 28 _name = "EmptyGangaObject" 29 _category = "internal" 30 _hidden = 1
31 32 # Error raised on schema version error
33 -class SchemaVersionError(GangaException):
34 - def __init__(self,what):
35 GangaException.__init__(self,what) 36 self.what=what
37 - def __str__(self):
38 return "SchemaVersionError: %s"%self.what
39
40 -class InaccessibleObjectError(GangaException):
41 - def __init__(self,repo,id,orig):
42 GangaException.__init__(self,"Inaccessible Object") 43 self.repo=repo 44 self.id=id 45 self.orig=orig
46 - def __str__(self):
47 return "Repository '%s' object #%s is not accessible because of an %s: %s"%(self.repo.registry.name,self.id,self.orig.__class__.__name__, str(self.orig))
48
49 -class RepositoryError(GangaException):
50 """ This error is raised if there is a fatal error in the repository."""
51 - def __init__(self,repo,what):
52 self.what=what 53 self.repository = repo 54 logger.error("A severe error occurred in the Repository '%s': %s" % (repo.registry.name, what)) 55 logger.error('If you believe the problem has been solved, type "reactivate()" to re-enable ') 56 disableInternalServices() 57 GangaException.__init__(self,what)
58
59 -class GangaRepository(object):
60 """ GangaRepository is the base class for repository backend implementations. 61 It provides an interface for developers of new backends. 62 The base class implements a transient Ganga Repository for testing purposes. 63 """
64 - def __init__(self, registry, locking = True):
65 """GangaRepository constructor. Initialization should be done in startup()""" 66 self.registry = registry 67 self.objects = {} 68 self.incomplete_objects = []
69 70 ## Functions that should be overridden and implemented by derived classes.
71 - def startup(self):
72 """startup() --> None 73 Connect to the repository. 74 Raise RepositoryError 75 """ 76 raise NotImplementedError
77
78 - def update_index(self, id = None):
79 """update_index(id = None) --> iterable of ids 80 Read the index containing the given ID (or all indices if id is None). 81 Create objects as needed , and set the _index_cache for all objects 82 that are not fully loaded. 83 Returns a list of ids of jobs that changed/removed/added 84 Raise RepositoryError 85 """ 86 raise NotImplementedError
87
88 - def shutdown(self):
89 """shutdown() --> None 90 Disconnect from the repository. 91 Raise RepositoryError 92 """ 93 raise NotImplementedError
94
95 - def add(self, objs, force_ids = None):
96 """add(objects) --> list of object IDs in this repository 97 Add the given objects to the repository and return their IDs 98 After successfully determining the id call _internal_setitem__(id,obj) 99 for each id/object pair. 100 WARNING: If forcing the IDs, no locking is done here! 101 Raise RepositoryError 102 """ 103 raise NotImplementedError
104
105 - def delete(self, ids):
106 """delete(ids) --> None 107 Delete the objects specified by the ids from the repository. 108 Assumes that the objects associated to the ids are locked (!) 109 Call _internal_del__(id) for each id to remove the GangaObject 110 from the Registry 111 Raise KeyError 112 Raise RepositoryError 113 """ 114 raise NotImplementedError
115
116 - def load(self, ids):
117 """load(ids) --> None 118 Load the objects specified by the ids from the persistency layer. 119 Raise KeyError 120 Raise RepositoryError 121 """ 122 raise NotImplementedError
123
124 - def flush(self, ids):
125 """flush(ids) --> None 126 Writes the objects specified by the ids to the persistency layer. 127 Raise KeyError 128 Raise RepositoryError 129 """ 130 raise NotImplementedError
131
132 - def lock(self,ids):
133 """lock(ids) --> bool 134 Locks the specified IDs against modification from other Ganga sessions 135 Raise RepositoryError 136 Returns successfully locked ids 137 """ 138 raise NotImplementedError
139
140 - def unlock(self,ids):
141 """unlock(ids) --> None 142 Unlock the specified IDs to allow another Ganga session to modify them 143 EXPERIMENTAL - does not have to be implemented. 144 """ 145 pass
146
147 - def clean(self):
148 """clear() --> None 149 Remove the Repository completely (rm -rf) and set it up again. 150 Very violent. Use with caution. 151 """ 152 pass
153 154 # Optional but suggested functions
155 - def get_lock_session(self,id):
156 """get_lock_session(id) 157 Tries to determine the session that holds the lock on id for information purposes, and return an informative string. 158 Returns None on failure 159 """ 160 return None
161
162 - def get_other_sessions(self):
163 """get_session_list() 164 Tries to determine the other sessions that are active and returns an informative string for each of them. 165 """ 166 return [] 167
168 - def reap_locks(self):
169 """reap_locks() --> True/False 170 Remotely clear all foreign locks from the session. 171 WARNING: This is not nice. 172 Returns True on success, False on error.""" 173 return False
174 175 # Internal helper functions for derived classed
176 - def _make_empty_object_(self, id, category, classname):
177 """Internal helper: adds an empty GangaObject of the given class to the repository. 178 Raise RepositoryError 179 Raise PluginManagerError if the class name is not found""" 180 cls = allPlugins.find(category, classname) 181 obj = super(cls, cls).__new__(cls) 182 obj._proxyObject = None 183 obj._data = None 184 185 self._internal_setitem__(id,obj) 186 return obj
187
188 - def _internal_setitem__(self, id, obj):
189 """ Internal function for repository classes to add items to the repository. 190 Should not raise any Exceptions 191 """ 192 if id in self.incomplete_objects: 193 self.incomplete_objects.remove(id) 194 self.objects[id] = obj 195 obj.__dict__["_registry_id"] = id 196 obj.__dict__["_registry_locked"] = False 197 if obj._data and "id" in obj._data.keys(): # MAGIC id 198 obj.id = id 199 obj._setRegistry(self.registry)
200
201 - def _internal_del__(self, id):
202 """ Internal function for repository classes to (logically) delete items to the repository.""" 203 if id in self.incomplete_objects: 204 self.incomplete_objects.remove(id) 205 else: 206 self.objects[id]._setRegistry(None) 207 del self.objects[id].__dict__["_registry_id"] 208 del self.objects[id].__dict__["_registry_locked"] 209 del self.objects[id]
210 211
212 -class GangaRepositoryTransient(object):
213 """This class implements a transient Ganga Repository for testing purposes. 214 """ 215 ## Functions that should be overridden and implemented by derived classes.
216 - def startup(self):
217 self._next_id = 0
218
219 - def update_index(self, id = None):
220 pass
221
222 - def shutdown(self):
223 pass
224
225 - def add(self, objs, force_ids = None):
226 assert force_ids is None or len(force_ids) == len(objs) 227 ids = [] 228 for i in range(len(objs)): 229 obj = objs[i] 230 if force_ids: 231 id = force_ids[i] 232 else: 233 id = self._next_id 234 self._internal_setitem__(id, obj) 235 ids.append(id) 236 self._next_id = max(self._next_id + 1, id + 1) 237 return ids
238
239 - def delete(self, ids):
240 for id in ids: 241 self._internal_del__(id)
242
243 - def load(self, ids):
244 pass
245
246 - def flush(self, ids):
247 pass
248
249 - def lock(self,ids):
250 return True
251
252 - def unlock(self,ids):
253 pass
254