changeset 444:b64e528fb524

server side: use of bridge's getReady to be sure that backend is initialised at launch
author Goffi <goffi@goffi.org>
date Thu, 15 May 2014 20:27:52 +0200
parents eca26481176f
children c0ff91cabea0
files libervia_server/__init__.py
diffstat 1 files changed, 57 insertions(+), 50 deletions(-) [+]
line wrap: on
line diff
--- a/libervia_server/__init__.py	Wed May 14 12:52:27 2014 +0200
+++ b/libervia_server/__init__.py	Thu May 15 20:27:52 2014 +0200
@@ -17,7 +17,7 @@
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-from twisted.application import internet, service
+from twisted.application import service
 from twisted.internet import glib2reactor
 glib2reactor.install()
 from twisted.internet import reactor, defer
@@ -715,7 +715,6 @@
 
         _session.notifyOnExpire(onExpire)
 
-        d = defer.Deferred()
         return result('LOGGED')
 
     def _logginError(self, login, request, error_type):
@@ -999,7 +998,7 @@
             # This part is not executed when the plugin is actually started.
             for name, value in [(option[0], option[2]) for option in self.OPT_PARAMETERS]:
                 kwargs[name] = value
-
+        self.initialised = defer.Deferred()
         self.connection_type = kwargs['connection_type']
         self.port = kwargs['port']
         self.port_https = kwargs['port_https']
@@ -1025,34 +1024,40 @@
         except BridgeExceptionNoService:
             print(u"Can't connect to SàT backend, are you sure it's launched ?")
             sys.exit(1)
-        self.bridge.register("connected", self.signal_handler.connected)
-        self.bridge.register("disconnected", self.signal_handler.disconnected)
-        self.bridge.register("connectionError", self.signal_handler.connectionError)
-        self.bridge.register("actionResult", self.action_handler.actionResultCb)
-        #core
-        for signal_name in ['presenceUpdate', 'newMessage', 'subscribe', 'contactDeleted', 'newContact', 'entityDataUpdated', 'askConfirmation', 'newAlert', 'paramUpdate']:
-            self.bridge.register(signal_name, self.signal_handler.getGenericCb(signal_name))
-        #plugins
-        for signal_name in ['personalEvent', 'roomJoined', 'roomUserJoined', 'roomUserLeft', 'tarotGameStarted', 'tarotGameNew', 'tarotGameChooseContrat',
-                            'tarotGameShowCards', 'tarotGameInvalidCards', 'tarotGameCardsPlayed', 'tarotGameYourTurn', 'tarotGameScore', 'tarotGamePlayers',
-                            'radiocolStarted', 'radiocolPreload', 'radiocolPlay', 'radiocolNoUpload', 'radiocolUploadOk', 'radiocolSongRejected', 'radiocolPlayers',
-                            'roomLeft', 'roomUserChangedNick', 'chatStateReceived']:
-            self.bridge.register(signal_name, self.signal_handler.getGenericCb(signal_name), "plugin")
-        self.media_dir = self.bridge.getConfig('', 'media_dir')
-        self.local_dir = self.bridge.getConfig('', 'local_dir')
-        root.putChild('', Redirect('libervia.html'))
-        root.putChild('json_signal_api', self.signal_handler)
-        root.putChild('json_api', MethodHandler(self))
-        root.putChild('register_api', _register)
-        root.putChild('upload_radiocol', _upload_radiocol)
-        root.putChild('upload_avatar', _upload_avatar)
-        root.putChild('blog', MicroBlog(self))
-        root.putChild('css', ProtectedFile("server_css/"))
-        root.putChild(os.path.dirname(C.MEDIA_DIR), ProtectedFile(self.media_dir))
-        root.putChild(os.path.dirname(C.AVATARS_DIR), ProtectedFile(os.path.join(self.local_dir, C.AVATARS_DIR)))
-        root.putChild('radiocol', ProtectedFile(_upload_radiocol.getTmpDir(), defaultType="audio/ogg")) #We cheat for PoC because we know we are on the same host, so we use directly upload dir
-        self.site = server.Site(root)
-        self.site.sessionFactory = LiberviaSession
+        def backendReady(dummy):
+            self.bridge.register("connected", self.signal_handler.connected)
+            self.bridge.register("disconnected", self.signal_handler.disconnected)
+            self.bridge.register("connectionError", self.signal_handler.connectionError)
+            self.bridge.register("actionResult", self.action_handler.actionResultCb)
+            #core
+            for signal_name in ['presenceUpdate', 'newMessage', 'subscribe', 'contactDeleted', 'newContact', 'entityDataUpdated', 'askConfirmation', 'newAlert', 'paramUpdate']:
+                self.bridge.register(signal_name, self.signal_handler.getGenericCb(signal_name))
+            #plugins
+            for signal_name in ['personalEvent', 'roomJoined', 'roomUserJoined', 'roomUserLeft', 'tarotGameStarted', 'tarotGameNew', 'tarotGameChooseContrat',
+                                'tarotGameShowCards', 'tarotGameInvalidCards', 'tarotGameCardsPlayed', 'tarotGameYourTurn', 'tarotGameScore', 'tarotGamePlayers',
+                                'radiocolStarted', 'radiocolPreload', 'radiocolPlay', 'radiocolNoUpload', 'radiocolUploadOk', 'radiocolSongRejected', 'radiocolPlayers',
+                                'roomLeft', 'roomUserChangedNick', 'chatStateReceived']:
+                self.bridge.register(signal_name, self.signal_handler.getGenericCb(signal_name), "plugin")
+            self.media_dir = self.bridge.getConfig('', 'media_dir')
+            self.local_dir = self.bridge.getConfig('', 'local_dir')
+            root.putChild('', Redirect('libervia.html'))
+            root.putChild('json_signal_api', self.signal_handler)
+            root.putChild('json_api', MethodHandler(self))
+            root.putChild('register_api', _register)
+            root.putChild('upload_radiocol', _upload_radiocol)
+            root.putChild('upload_avatar', _upload_avatar)
+            root.putChild('blog', MicroBlog(self))
+            root.putChild('css', ProtectedFile("server_css/"))
+            root.putChild(os.path.dirname(C.MEDIA_DIR), ProtectedFile(self.media_dir))
+            root.putChild(os.path.dirname(C.AVATARS_DIR), ProtectedFile(os.path.join(self.local_dir, C.AVATARS_DIR)))
+            root.putChild('radiocol', ProtectedFile(_upload_radiocol.getTmpDir(), defaultType="audio/ogg")) #We cheat for PoC because we know we are on the same host, so we use directly upload dir
+            self.site = server.Site(root)
+            self.site.sessionFactory = LiberviaSession
+
+        self.bridge.getReady(lambda: self.initialised.callback(None),
+                             lambda failure: self.initialised.errback(Exception(failure)))
+        self.initialised.addCallback(backendReady)
+        self.initialised.addErrback(lambda failure: log.error("Init error: %s" % failure))
 
     def addCleanup(self, callback, *args, **kwargs):
         """Add cleaning method to call when service is stopped
@@ -1063,25 +1068,27 @@
         self._cleanup.insert(0, (callback, args, kwargs))
 
     def startService(self):
-        if self.connection_type in ('https', 'both'):
-            if not ssl_available:
-                raise(ImportError(_("Python module pyOpenSSL is not installed!")))
-            try:
-                with open(os.path.expanduser(self.ssl_certificate)) as keyAndCert:
-                    try:
-                        cert = ssl.PrivateCertificate.loadPEM(keyAndCert.read())
-                    except OpenSSL.crypto.Error as e:
-                        log.error(_("The file '%s' must contain both private and public parts of the certificate") % self.ssl_certificate)
-                        raise e
-            except IOError as e:
-                log.error(_("The file '%s' doesn't exist") % self.ssl_certificate)
-                raise e
-            reactor.listenSSL(self.port_https, self.site, cert.options())
-        if self.connection_type in ('http', 'both'):
-            if self.connection_type == 'both' and self.redirect_to_https:
-                reactor.listenTCP(self.port, server.Site(RedirectToHTTPS(self.port, self.port_https_ext)))
-            else:
-                reactor.listenTCP(self.port, self.site)
+        def initOk(dummy):
+            if self.connection_type in ('https', 'both'):
+                if not ssl_available:
+                    raise(ImportError(_("Python module pyOpenSSL is not installed!")))
+                try:
+                    with open(os.path.expanduser(self.ssl_certificate)) as keyAndCert:
+                        try:
+                            cert = ssl.PrivateCertificate.loadPEM(keyAndCert.read())
+                        except OpenSSL.crypto.Error as e:
+                            log.error(_("The file '%s' must contain both private and public parts of the certificate") % self.ssl_certificate)
+                            raise e
+                except IOError as e:
+                    log.error(_("The file '%s' doesn't exist") % self.ssl_certificate)
+                    raise e
+                reactor.listenSSL(self.port_https, self.site, cert.options())
+            if self.connection_type in ('http', 'both'):
+                if self.connection_type == 'both' and self.redirect_to_https:
+                    reactor.listenTCP(self.port, server.Site(RedirectToHTTPS(self.port, self.port_https_ext)))
+                else:
+                    reactor.listenTCP(self.port, self.site)
+        self.initialised.addCallback(initOk)
 
     def stopService(self):
         print "launching cleaning methods"