Mercurial > libervia-backend
comparison 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 |
comparison
equal
deleted
inserted
replaced
3041:72583524cfd3 | 3042:964abd07dc03 |
---|---|
15 # GNU Affero General Public License for more details. | 15 # GNU Affero General Public License for more details. |
16 | 16 |
17 # You should have received a copy of the GNU Affero General Public License | 17 # You should have received a copy of the GNU Affero General Public License |
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. | 18 # along with this program. If not, see <http://www.gnu.org/licenses/>. |
19 | 19 |
20 import asyncio | |
21 import dbus | |
22 import ast | |
20 from sat.core.i18n import _ | 23 from sat.core.i18n import _ |
21 from bridge_frontend import BridgeException | 24 from .bridge_frontend import BridgeException |
22 import dbus | |
23 from sat.core.log import getLogger | 25 from sat.core.log import getLogger |
26 from sat.core.exceptions import BridgeExceptionNoService, BridgeInitError | |
27 from dbus.mainloop.glib import DBusGMainLoop | |
28 | |
29 DBusGMainLoop(set_as_default=True) | |
24 log = getLogger(__name__) | 30 log = getLogger(__name__) |
25 from sat.core.exceptions import BridgeExceptionNoService, BridgeInitError | |
26 | 31 |
27 from dbus.mainloop.glib import DBusGMainLoop | |
28 DBusGMainLoop(set_as_default=True) | |
29 | |
30 import ast | |
31 | 32 |
32 const_INT_PREFIX = "org.salutatoi.SAT" # Interface prefix | 33 const_INT_PREFIX = "org.salutatoi.SAT" # Interface prefix |
33 const_ERROR_PREFIX = const_INT_PREFIX + ".error" | 34 const_ERROR_PREFIX = const_INT_PREFIX + ".error" |
34 const_OBJ_PATH = '/org/salutatoi/SAT/bridge' | 35 const_OBJ_PATH = '/org/salutatoi/SAT/bridge' |
35 const_CORE_SUFFIX = ".core" | 36 const_CORE_SUFFIX = ".core" |
57 except (SyntaxError, ValueError, TypeError): | 58 except (SyntaxError, ValueError, TypeError): |
58 condition = '' | 59 condition = '' |
59 return BridgeException(name, message, condition) | 60 return BridgeException(name, message, condition) |
60 | 61 |
61 | 62 |
62 class Bridge(object): | 63 class Bridge: |
63 | 64 |
64 def bridgeConnect(self, callback, errback): | 65 def bridgeConnect(self, callback, errback): |
65 try: | 66 try: |
66 self.sessions_bus = dbus.SessionBus() | 67 self.sessions_bus = dbus.SessionBus() |
67 self.db_object = self.sessions_bus.get_object(const_INT_PREFIX, | 68 self.db_object = self.sessions_bus.get_object(const_INT_PREFIX, |
77 elif e._dbus_error_name == 'org.freedesktop.DBus.Error.NotSupported': | 78 elif e._dbus_error_name == 'org.freedesktop.DBus.Error.NotSupported': |
78 log.error(_("D-Bus is not launched, please see README to see instructions on how to launch it")) | 79 log.error(_("D-Bus is not launched, please see README to see instructions on how to launch it")) |
79 errback(BridgeInitError) | 80 errback(BridgeInitError) |
80 else: | 81 else: |
81 errback(e) | 82 errback(e) |
82 callback() | 83 else: |
84 callback() | |
83 #props = self.db_core_iface.getProperties() | 85 #props = self.db_core_iface.getProperties() |
84 | 86 |
85 def register_signal(self, functionName, handler, iface="core"): | 87 def register_signal(self, functionName, handler, iface="core"): |
86 if iface == "core": | 88 if iface == "core": |
87 self.db_core_iface.connect_to_signal(functionName, handler) | 89 self.db_core_iface.connect_to_signal(functionName, handler) |
135 return method(*args, **kwargs) | 137 return method(*args, **kwargs) |
136 | 138 |
137 return getPluginMethod | 139 return getPluginMethod |
138 | 140 |
139 ##METHODS_PART## | 141 ##METHODS_PART## |
142 | |
143 class AIOBridge(Bridge): | |
144 | |
145 def register_signal(self, functionName, handler, iface="core"): | |
146 loop = asyncio.get_running_loop() | |
147 async_handler = lambda *args: asyncio.run_coroutine_threadsafe(handler(*args), loop) | |
148 return super().register_signal(functionName, async_handler, iface) | |
149 | |
150 def __getattribute__(self, name): | |
151 """ usual __getattribute__ if the method exists, else try to find a plugin method """ | |
152 try: | |
153 return object.__getattribute__(self, name) | |
154 except AttributeError: | |
155 # The attribute is not found, we try the plugin proxy to find the requested method | |
156 def getPluginMethod(*args, **kwargs): | |
157 loop = asyncio.get_running_loop() | |
158 fut = loop.create_future() | |
159 method = getattr(self.db_plugin_iface, name) | |
160 reply_handler = lambda ret=None: loop.call_soon_threadsafe( | |
161 fut.set_result, ret) | |
162 error_handler = lambda err: loop.call_soon_threadsafe( | |
163 fut.set_exception, dbus_to_bridge_exception(err)) | |
164 method( | |
165 *args, | |
166 **kwargs, | |
167 timeout=const_TIMEOUT, | |
168 reply_handler=reply_handler, | |
169 error_handler=error_handler | |
170 ) | |
171 return fut | |
172 | |
173 return getPluginMethod | |
174 | |
175 def bridgeConnect(self): | |
176 loop = asyncio.get_running_loop() | |
177 fut = loop.create_future() | |
178 super().bridgeConnect( | |
179 callback=lambda: loop.call_soon_threadsafe(fut.set_result, None), | |
180 errback=lambda e: loop.call_soon_threadsafe(fut.set_exception, e) | |
181 ) | |
182 return fut | |
183 | |
184 ##ASYNC_METHODS_PART## |