bitbake: prserv/serv: Multithread the server
authorRichard Purdie <richard.purdie@linuxfoundation.org>
Wed, 28 Aug 2013 16:10:09 +0000 (16:10 +0000)
committerRichard Purdie <richard.purdie@linuxfoundation.org>
Wed, 28 Aug 2013 23:13:22 +0000 (00:13 +0100)
This makes the PR server multithreaded and able to handle multiple connections
at once which means its no longer a build bottle neck when serving one connection
at a time. I've experimented and database connection for each thread seems to
cause the least issues, pushing the contention for sqllite to handle itself.

This means moving the db/table connection code into the actual function methods.
It doesn't abstract well as a function since we need the db object around for
the lifetime of the function as well as the table else we lose the connection.

(Bitbake rev: bf9be2029b2bded5f532bdda4c38ae3dff5d1cf6)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
bitbake/lib/prserv/serv.py

index d6f3f44..3677f77 100644 (file)
@@ -31,19 +31,20 @@ class Handler(SimpleXMLRPCRequestHandler):
 PIDPREFIX = "/tmp/PRServer_%s_%s.pid"
 singleton = None
 
-class PRServer(SimpleXMLRPCServer):
+import SocketServer
+class SimpleThreadedXMLRPCServer(SocketServer.ThreadingMixIn, SimpleXMLRPCServer):
+    pass
+
+class PRServer(SimpleThreadedXMLRPCServer):
     def __init__(self, dbfile, logfile, interface, daemon=True):
         ''' constructor '''
-        SimpleXMLRPCServer.__init__(self, interface,
-                                    requestHandler=SimpleXMLRPCRequestHandler,
+        SimpleThreadedXMLRPCServer.__init__(self, interface,
                                     logRequests=False, allow_none=True)
         self.dbfile=dbfile
         self.daemon=daemon
         self.logfile=logfile
         self.working_thread=None
         self.host, self.port = self.socket.getsockname()
-        self.db=prserv.db.PRData(dbfile)
-        self.table=self.db["PRMAIN"]
         self.pidfile=PIDPREFIX % (self.host, self.port)
 
         self.register_function(self.getPR, "getPR")
@@ -55,13 +56,17 @@ class PRServer(SimpleXMLRPCServer):
 
     def export(self, version=None, pkgarch=None, checksum=None, colinfo=True):
         try:
-            return self.table.export(version, pkgarch, checksum, colinfo)
+            db = prserv.db.PRData(self.dbfile)
+            table = db["PRMAIN"]
+            return table.export(version, pkgarch, checksum, colinfo)
         except sqlite3.Error as exc:
             logger.error(str(exc))
             return None
 
     def importone(self, version, pkgarch, checksum, value):
-        return self.table.importone(version, pkgarch, checksum, value)
+        db = prserv.db.PRData(self.dbfile)
+        table = db["PRMAIN"]
+        return table.importone(version, pkgarch, checksum, value)
 
     def ping(self):
         return not self.quit
@@ -71,7 +76,9 @@ class PRServer(SimpleXMLRPCServer):
 
     def getPR(self, version, pkgarch, checksum):
         try:
-            return self.table.getValue(version, pkgarch, checksum)
+            db = prserv.db.PRData(self.dbfile)
+            table = db["PRMAIN"]
+            return table.getValue(version, pkgarch, checksum)
         except prserv.NotFoundError:
             logger.error("can not find value for (%s, %s)",version, checksum)
             return None
@@ -177,7 +184,6 @@ class PRServSingleton(object):
         self.prserv = PRServer(self.dbfile, self.logfile, self.interface)
         self.prserv.start()
         self.host, self.port = self.prserv.getinfo()
-        del self.prserv.db
 
     def getinfo(self):
         return (self.host, self.port)