Use cached ACLs
[invirt/packages/invirt-web.git] / webcommon.py
index 01b820a..1b39a2c 100644 (file)
@@ -1,6 +1,6 @@
 """Exceptions for the web interface."""
 
-from sipb_xen_database import Machine
+from sipb_xen_database import Machine, MachineAccess
 
 class MyException(Exception):
     """Base class for my exceptions"""
@@ -24,21 +24,32 @@ class CodeError(MyException):
 
 import controls
 
+def cachedproperty(func):
+    name = '__cache_' + func.__name__ + '_' + str(id(func))
+    def getter(self):
+        try:
+            return getattr(self, name)
+        except AttributeError:
+            value = func(self)
+            setattr(self, name, value)
+            return value
+    return property(getter)
+
 class Global(object):
     """Global state of the system, to avoid duplicate remctls to get state"""
     def __init__(self, user):
         self.user = user
-
-    def __get_uptimes(self):
-        if not hasattr(self, '_uptimes'):
-            self._uptimes = controls.getUptimes(Machine.select())
-        return self._uptimes
-    uptimes = property(__get_uptimes)
+    
+    machines = cachedproperty(lambda self: 
+                             [ma.machine for ma in 
+                              MachineAccess.select_by(user=self.user)])
+    uptimes = cachedproperty(lambda self: 
+                             controls.getUptimes(self.machines))
 
     def clear(self):
         """Clear the state so future accesses reload it."""
-        for attr in ('_uptimes', ):
-            if hasattr(self, attr):
+        for attr in self.__dict__:
+            if attr.startswith('__cache_'):
                 delattr(self, attr)
 
 g = Global(None)