Switched from caching ORM to direct database queries; now uncached queries are almost... invirt-remote-server/0.1.3
authorQuentin Smith <quentin@mit.edu>
Fri, 21 Nov 2008 09:16:38 +0000 (04:16 -0500)
committerQuentin Smith <quentin@mit.edu>
Fri, 21 Nov 2008 09:16:38 +0000 (04:16 -0500)
svn path=/trunk/packages/invirt-remote-server/; revision=1728

debian/changelog
files/usr/sbin/invirt-remconffs

index 3f13ae1..68319d3 100644 (file)
@@ -1,3 +1,11 @@
+invirt-remote-server (0.1.3) unstable; urgency=low
+
+  * Switched to using "raw" select expressions instead of using the ORM;
+    allows the same speed as the old object-based system but without any
+    caching necessary.
+
+ -- Quentin Smith <quentin@mit.edu>  Fri, 21 Nov 2008 04:15:50 -0500
+
 invirt-remote-server (0.1.2) unstable; urgency=low
 
   * Update remctl help with new reboot functionality
index f4d88b8..6389391 100755 (executable)
@@ -5,6 +5,7 @@ from routes import Mapper
 
 from syslog import *
 from time import time
+import sqlalchemy as sa
 
 from invirt import database
 from invirt.config import structs as config
@@ -27,7 +28,6 @@ class RemConfFS(routefs.RouteFS):
         the user who mounts the filesystem (i.e. root)
         """
         super(RemConfFS, self).__init__(*args, **kw)
-        self.lasttime = 0
         self.fuse_args.add("allow_other", True)
         
         openlog('invirt-remconffs ', LOG_PID, LOG_DAEMON)
@@ -42,22 +42,20 @@ class RemConfFS(routefs.RouteFS):
         m.connect('conf', controller='getconf')
         return m
     
-    def recache(self):
-        if time() - self.lasttime > 5:
-            self.lasttime = time()
-            database.clear_cache()
-            self.machines = dict((machine.name, machine) for machine in database.session.query(database.Machine).all())
-    
     def getroot(self, **kw):
         return ['acl', 'conf']
     
     def getacl(self, machine, **kw):
         """Build the ACL file for a machine
         """
-        self.recache()
-        machine = self.machines[machine]
-        users = [acl.user for acl in machine.acl]
-        return "\n".join(map(self.userToPrinc, users)
+        s = sa.sql.select([database.machine_access_table.c.user], # Field to select from
+                          sa.sql.and_( # where clause
+                database.machine_table.c.machine_id==database.machine_access_table.c.machine_id, # join field
+                database.machine_table.c.name == machine), # filter field
+                          from_obj=[database.machine_access_table, database.machine_table]) # from tables
+        users = [self.userToPrinc(acl[0]) for acl in
+                 database.session.execute(s)]
+        return "\n".join(users
                  + ['include /etc/remctl/acl/web',
                     ''])
     
@@ -70,10 +68,8 @@ class RemConfFS(routefs.RouteFS):
                  for machine_name in self.getmachines())+'\n'
     
     def getmachines(self, **kw):
-        """Get the list of VMs in the database, clearing the cache if it's 
-        older than 15 seconds"""
-        self.recache()
-        return self.machines.keys()
+        """Get the list of VMs in the database. Does not cache to prevent race conditions."""
+        return list(row[0] for row in database.session.execute(sa.sql.select([database.Machine.c.name])))
     
     def userToPrinc(self, user):
         """Convert Kerberos v4-style names to v5-style and append a default