# HG changeset patch # User Goffi # Date 1631092581 -7200 # Node ID 71cfe9334f73d3cf6f988a2ca5305d4bb6679fb9 # Parent 57d43e3e0095f25251b2d091e2b9a7e98b73704b bridge (dbus/frontend): reintrospect signature in case of guess error: When a "Unable to guess signature […]" `ValueError` is raised during a method call, the signatures are re-introspected. This should fix this issue when a frontend is launched just after to the backend (this happens notably with tests). diff -r 57d43e3e0095 -r 71cfe9334f73 sat/bridge/bridge_constructor/constructors/dbus/dbus_frontend_template.py --- a/sat/bridge/bridge_constructor/constructors/dbus/dbus_frontend_template.py Wed Sep 08 11:16:00 2021 +0200 +++ b/sat/bridge/bridge_constructor/constructors/dbus/dbus_frontend_template.py Wed Sep 08 11:16:21 2021 +0200 @@ -140,7 +140,21 @@ kwargs['reply_handler'] = _callback kwargs['error_handler'] = lambda err: _errback(dbus_to_bridge_exception(err)) - return method(*args, **kwargs) + try: + return method(*args, **kwargs) + except ValueError as e: + if e.args[0].startswith("Unable to guess signature"): + # XXX: if frontend is started too soon after backend, the + # inspection misses methods (notably plugin dynamically added + # methods). The following hack works around that by redoing the + # cache of introspected methods signatures. + log.debug("using hack to work around inspection issue") + proxy = self.db_plugin_iface.proxy_object + IN_PROGRESS = proxy.INTROSPECT_STATE_INTROSPECT_IN_PROGRESS + proxy._introspect_state = IN_PROGRESS + proxy._Introspect() + return self.db_plugin_iface.get_dbus_method(name)(*args, **kwargs) + raise e return getPluginMethod @@ -167,13 +181,32 @@ 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 - ) + try: + method( + *args, + **kwargs, + timeout=const_TIMEOUT, + reply_handler=reply_handler, + error_handler=error_handler + ) + except ValueError as e: + if e.args[0].startswith("Unable to guess signature"): + # same hack as for Bridge.__getattribute__ + log.warning("using hack to work around inspection issue") + proxy = self.db_plugin_iface.proxy_object + IN_PROGRESS = proxy.INTROSPECT_STATE_INTROSPECT_IN_PROGRESS + proxy._introspect_state = IN_PROGRESS + proxy._Introspect() + self.db_plugin_iface.get_dbus_method(name)( + *args, + **kwargs, + timeout=const_TIMEOUT, + reply_handler=reply_handler, + error_handler=error_handler + ) + + else: + raise e return fut return getPluginMethod diff -r 57d43e3e0095 -r 71cfe9334f73 sat_frontends/bridge/dbus_bridge.py --- a/sat_frontends/bridge/dbus_bridge.py Wed Sep 08 11:16:00 2021 +0200 +++ b/sat_frontends/bridge/dbus_bridge.py Wed Sep 08 11:16:21 2021 +0200 @@ -140,7 +140,21 @@ kwargs['reply_handler'] = _callback kwargs['error_handler'] = lambda err: _errback(dbus_to_bridge_exception(err)) - return method(*args, **kwargs) + try: + return method(*args, **kwargs) + except ValueError as e: + if e.args[0].startswith("Unable to guess signature"): + # XXX: if frontend is started too soon after backend, the + # inspection misses methods (notably plugin dynamically added + # methods). The following hack works around that by redoing the + # cache of introspected methods signatures. + log.debug("using hack to work around inspection issue") + proxy = self.db_plugin_iface.proxy_object + IN_PROGRESS = proxy.INTROSPECT_STATE_INTROSPECT_IN_PROGRESS + proxy._introspect_state = IN_PROGRESS + proxy._Introspect() + return self.db_plugin_iface.get_dbus_method(name)(*args, **kwargs) + raise e return getPluginMethod @@ -930,13 +944,32 @@ 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 - ) + try: + method( + *args, + **kwargs, + timeout=const_TIMEOUT, + reply_handler=reply_handler, + error_handler=error_handler + ) + except ValueError as e: + if e.args[0].startswith("Unable to guess signature"): + # same hack as for Bridge.__getattribute__ + log.warning("using hack to work around inspection issue") + proxy = self.db_plugin_iface.proxy_object + IN_PROGRESS = proxy.INTROSPECT_STATE_INTROSPECT_IN_PROGRESS + proxy._introspect_state = IN_PROGRESS + proxy._Introspect() + self.db_plugin_iface.get_dbus_method(name)( + *args, + **kwargs, + timeout=const_TIMEOUT, + reply_handler=reply_handler, + error_handler=error_handler + ) + + else: + raise e return fut return getPluginMethod