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
This commit is contained in:
Goffi 2011-11-07 00:09:22 +01:00
commit 19232e8a6b
3 changed files with 250 additions and 166 deletions

View file

@ -393,14 +393,14 @@ class DbusConstructor(Constructor):
completion['args_result'] = self.getArguments(function['sig_in'], name=arg_doc, unicode_protect=self.options.unicode)
completion['async_comma'] = ', ' if async and function['sig_in'] else ''
completion['async_args_def'] = 'callback=None, errback=None' if async else ''
completion['async_args_call'] = 'callback, lambda arg:errback(GenericException(arg))' if async else ''
completion['async_args_call'] = 'callback=callback, errback=errback' if async else ''
completion['async_callbacks'] = "('callback', 'errback')" if async else "None"
methods_part.append("""\
@dbus.service.method(const_INT_PREFIX+const_%(category)s_SUFFIX,
in_signature='%(sig_in)s', out_signature='%(sig_out)s',
async_callbacks=%(async_callbacks)s)
def %(name)s(self, %(args)s%(async_comma)s%(async_args_def)s):
%(debug)sreturn self.cb["%(name)s"](%(args_result)s%(async_comma)s%(async_args_call)s)
%(debug)sreturn self._callback("%(name)s", %(args_result)s%(async_comma)s%(async_args_call)s)
""" % completion)
#at this point, signals_part, methods_part and direct_calls should be filled,

View file

@ -195,7 +195,6 @@ doc_return=callback is called when profile actually exists in database and memor
errback is called with error constant as parameter:
- "CONFLICT": The profile name already exists
- "CANCELED": profile creation canceled
- "DATABASE": profile creation in database failed
[deleteProfile]
type=method
@ -396,6 +395,7 @@ doc_param_2=attribute: Name of the attribute
doc_param_3=%(doc_profile_key)s
[getParamsUI]
async=
type=method
category=core
sig_in=s
@ -405,6 +405,7 @@ doc=Return a SàT XMLUI for parameters
doc_param_0=%(doc_profile_key)s
[getParams]
async=
type=method
category=core
sig_in=s
@ -414,6 +415,7 @@ doc=Return XML of parameters
doc_param_0=%(doc_profile_key)s
[getParamsForCategory]
async=
type=method
category=core
sig_in=ss

View file

@ -24,7 +24,8 @@ from bridge import Bridge
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_OBJ_PATH = '/org/goffi/SAT/bridge'
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 @@ class DbusObject(dbus.service.Object):
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,