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).
This commit is contained in:
Goffi 2021-09-08 11:16:21 +02:00
commit f29a6bfa17
2 changed files with 82 additions and 16 deletions

View file

@ -140,7 +140,21 @@ class Bridge:
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 @@ class AIOBridge(Bridge):
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

View file

@ -140,7 +140,21 @@ class Bridge:
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 @@ class AIOBridge(Bridge):
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