diff src/bridge/bridge_constructor/dbus_core_template.py @ 423:6c20c76abdcc

backend: - bridge async D-Bus method now automatically manage callback and errback, we just have to return a deferred - getParams, getParamsForCategory and getParamsUI are now asynchronous primitivus: management of asynchronous getParamsUI
author Goffi <goffi@goffi.org>
date Mon, 07 Nov 2011 00:09:22 +0100
parents 6c167a2e04b8
children 72c13313b6d6
line wrap: on
line diff
--- a/src/bridge/bridge_constructor/dbus_core_template.py	Sun Nov 06 15:19:51 2011 +0100
+++ b/src/bridge/bridge_constructor/dbus_core_template.py	Mon Nov 07 00:09:22 2011 +0100
@@ -24,7 +24,8 @@
 import dbus
 import dbus.service
 import dbus.mainloop.glib
-from logging import debug, info
+from logging import debug, info, error
+from twisted.internet.defer import Deferred
 
 const_INT_PREFIX = "org.goffi.SAT"  #Interface prefix
 const_ERROR_PREFIX = const_INT_PREFIX+".error"
@@ -32,10 +33,20 @@
 const_CORE_SUFFIX = ".core"
 const_PLUGIN_SUFFIX = ".plugin"
 
+class MethodNotRegistered(dbus.DBusException):
+    _dbus_error_name = const_ERROR_PREFIX + ".MethodNotRegistered"
+
+class InternalError(dbus.DBusException):
+    _dbus_error_name = const_ERROR_PREFIX + ".InternalError"
+
+class AsyncNotDeferred(dbus.DBusException):
+    _dbus_error_name = const_ERROR_PREFIX + ".AsyncNotDeferred"
+
 class GenericException(dbus.DBusException):
-    def __init__(self, name):
+    def __init__(self, twisted_error):
         super(GenericException,self).__init__()
-        self._dbus_error_name = const_ERROR_PREFIX+"."+name
+        mess = twisted_error.getErrorMessage()
+        self._dbus_error_name = const_ERROR_PREFIX+"."+ (mess or str(err.__class__))
 
 class DbusObject(dbus.service.Object):
 
@@ -47,6 +58,32 @@
     def register(self, name, cb):
         self.cb[name]=cb
 
+    def _callback(self, name, *args, **kwargs):
+        """call the callback if it exists, raise an exception else
+        if the callback return a deferred, use async methods"""
+        if not name in self.cb:
+            raise MethodNotRegistered
+
+        if "callback" in kwargs:
+            #we must have errback too
+            if not "errback" in kwargs:
+                error("errback is missing in method call [%s]" % name)
+                raise InternalError
+            callback = kwargs.pop("callback")
+            errback = kwargs.pop("errback")
+            async = True
+        else:
+            async = False
+        result = self.cb[name](*args, **kwargs)
+        if async:
+            if not isinstance(result, Deferred):
+                error("Asynchrone method [%s] does not return a Deferred." % name)
+                raise AsyncNotDeferred
+            result.addCallback(callback)
+            result.addErrback(lambda err:errback(GenericException(err)))
+        else:
+            return result
+
     ### signals ###    
 
     @dbus.service.signal(const_INT_PREFIX+const_PLUGIN_SUFFIX,