Tweak visualisation process startup to connect to the database later

Allow for the main process to potentially do database
updates (e.g. schema changes), before we start the visualisation
code. In the visualisation code, wait for a signal from the main
process before connecting.

Change-Id: I0ac06763d882c3d6e13fb8aa92db361c73afdd54
diff --git a/visualisation/visualisation.py b/visualisation/visualisation.py
index e1b000b..e73c860 100644
--- a/visualisation/visualisation.py
+++ b/visualisation/visualisation.py
@@ -22,7 +22,7 @@
 #  graphics on demand.
 #
 
-import os, sys, logging, time, datetime, re
+import os, sys, logging, time, datetime, re, signal
 from multiprocessing import Process
 from BaseHTTPServer import BaseHTTPRequestHandler
 from BaseHTTPServer import HTTPServer
@@ -67,12 +67,14 @@
         self.p = Process(target=self.visloop, args=())
         self.p.start()
 
+    def _receive_signal(self, signum, stack):
+        if signum == signal.SIGUSR1:
+            self.state.db_ok = True
+
     # The main loop for the visualisation webserver
     def visloop(self):
+        self.state.db_ok = False
         self.state.cache = GraphicsCache()
-        self.state.db = VlanDB(db_name=self.state.config.database.dbname,
-                               username=self.state.config.database.username,
-                               readonly=True)
 
         loglevel = VlanUtil().set_logging_level(self.state.config.logging.level)
 
@@ -88,6 +90,18 @@
                                 filemode = 'a')
             logging.info('%s visualisation starting up', self.state.banner)
 
+        # Wait for main process to signal to us that it's finished with any
+        # database upgrades and we can open it without any problems.
+        signal.signal(signal.SIGUSR1, self._receive_signal)
+        while not self.state.db_ok:
+            logging.info('%s visualisation waiting for db_ok signal', self.state.banner)
+            time.sleep(1)
+        logging.info('%s visualisation received db_ok signal', self.state.banner)
+
+        self.state.db = VlanDB(db_name=self.state.config.database.dbname,
+                               username=self.state.config.database.username,
+                               readonly=True)
+
         server = VlandHTTPServer(('', self.state.config.visualisation.port),
                                  GetHandler, self.state)
         server.serve_forever()
@@ -96,6 +110,10 @@
     def shutdown(self):
         self.p.terminate()
 
+    # Kill the webserver
+    def signal_db_ok(self):
+        os.kill(self.p.pid, signal.SIGUSR1)
+
 class GetHandler(BaseHTTPRequestHandler):
     """ Methods to generate and serve the pages """