Mercurial > libervia-backend
diff sat/bridge/bridge_constructor/constructors/dbus/dbus_frontend_template.py @ 3042:964abd07dc03
bridge (dbus): AsyncIO version of D-Bus bridge:
The frontends D-Bus bridge has now an AIOBridge version which can be instantiated to use asyncio (the loop must be managed by frontends).
author | Goffi <goffi@goffi.org> |
---|---|
date | Tue, 01 Oct 2019 22:49:10 +0200 |
parents | ab2696e34d29 |
children | 9d0df638c8b4 |
line wrap: on
line diff
--- a/sat/bridge/bridge_constructor/constructors/dbus/dbus_frontend_template.py Tue Oct 01 22:49:06 2019 +0200 +++ b/sat/bridge/bridge_constructor/constructors/dbus/dbus_frontend_template.py Tue Oct 01 22:49:10 2019 +0200 @@ -17,17 +17,18 @@ # 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 sat.core.i18n import _ -from bridge_frontend import BridgeException +import asyncio import dbus +import ast +from sat.core.i18n import _ +from .bridge_frontend import BridgeException from sat.core.log import getLogger -log = getLogger(__name__) from sat.core.exceptions import BridgeExceptionNoService, BridgeInitError +from dbus.mainloop.glib import DBusGMainLoop -from dbus.mainloop.glib import DBusGMainLoop DBusGMainLoop(set_as_default=True) +log = getLogger(__name__) -import ast const_INT_PREFIX = "org.salutatoi.SAT" # Interface prefix const_ERROR_PREFIX = const_INT_PREFIX + ".error" @@ -59,7 +60,7 @@ return BridgeException(name, message, condition) -class Bridge(object): +class Bridge: def bridgeConnect(self, callback, errback): try: @@ -79,7 +80,8 @@ errback(BridgeInitError) else: errback(e) - callback() + else: + callback() #props = self.db_core_iface.getProperties() def register_signal(self, functionName, handler, iface="core"): @@ -137,3 +139,46 @@ return getPluginMethod ##METHODS_PART## + +class AIOBridge(Bridge): + + def register_signal(self, functionName, handler, iface="core"): + loop = asyncio.get_running_loop() + async_handler = lambda *args: asyncio.run_coroutine_threadsafe(handler(*args), loop) + return super().register_signal(functionName, async_handler, iface) + + def __getattribute__(self, name): + """ usual __getattribute__ if the method exists, else try to find a plugin method """ + try: + return object.__getattribute__(self, name) + except AttributeError: + # The attribute is not found, we try the plugin proxy to find the requested method + def getPluginMethod(*args, **kwargs): + loop = asyncio.get_running_loop() + fut = loop.create_future() + method = getattr(self.db_plugin_iface, name) + reply_handler = lambda ret=None: loop.call_soon_threadsafe( + fut.set_result, ret) + error_handler = lambda err: loop.call_soon_threadsafe( + fut.set_exception, dbus_to_bridge_exception(err)) + method( + *args, + **kwargs, + timeout=const_TIMEOUT, + reply_handler=reply_handler, + error_handler=error_handler + ) + return fut + + return getPluginMethod + + def bridgeConnect(self): + loop = asyncio.get_running_loop() + fut = loop.create_future() + super().bridgeConnect( + callback=lambda: loop.call_soon_threadsafe(fut.set_result, None), + errback=lambda e: loop.call_soon_threadsafe(fut.set_exception, e) + ) + return fut + +##ASYNC_METHODS_PART##