comparison sat/bridge/bridge_constructor/constructors/dbus/dbus_frontend_template.py @ 3648:71cfe9334f73

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).
author Goffi <goffi@goffi.org>
date Wed, 08 Sep 2021 11:16:21 +0200
parents 7550ae9cfbac
children 524856bd7b19
comparison
equal deleted inserted replaced
3647:57d43e3e0095 3648:71cfe9334f73
138 if async_: 138 if async_:
139 kwargs['timeout'] = const_TIMEOUT 139 kwargs['timeout'] = const_TIMEOUT
140 kwargs['reply_handler'] = _callback 140 kwargs['reply_handler'] = _callback
141 kwargs['error_handler'] = lambda err: _errback(dbus_to_bridge_exception(err)) 141 kwargs['error_handler'] = lambda err: _errback(dbus_to_bridge_exception(err))
142 142
143 return method(*args, **kwargs) 143 try:
144 return method(*args, **kwargs)
145 except ValueError as e:
146 if e.args[0].startswith("Unable to guess signature"):
147 # XXX: if frontend is started too soon after backend, the
148 # inspection misses methods (notably plugin dynamically added
149 # methods). The following hack works around that by redoing the
150 # cache of introspected methods signatures.
151 log.debug("using hack to work around inspection issue")
152 proxy = self.db_plugin_iface.proxy_object
153 IN_PROGRESS = proxy.INTROSPECT_STATE_INTROSPECT_IN_PROGRESS
154 proxy._introspect_state = IN_PROGRESS
155 proxy._Introspect()
156 return self.db_plugin_iface.get_dbus_method(name)(*args, **kwargs)
157 raise e
144 158
145 return getPluginMethod 159 return getPluginMethod
146 160
147 ##METHODS_PART## 161 ##METHODS_PART##
148 162
165 method = getattr(self.db_plugin_iface, name) 179 method = getattr(self.db_plugin_iface, name)
166 reply_handler = lambda ret=None: loop.call_soon_threadsafe( 180 reply_handler = lambda ret=None: loop.call_soon_threadsafe(
167 fut.set_result, ret) 181 fut.set_result, ret)
168 error_handler = lambda err: loop.call_soon_threadsafe( 182 error_handler = lambda err: loop.call_soon_threadsafe(
169 fut.set_exception, dbus_to_bridge_exception(err)) 183 fut.set_exception, dbus_to_bridge_exception(err))
170 method( 184 try:
171 *args, 185 method(
172 **kwargs, 186 *args,
173 timeout=const_TIMEOUT, 187 **kwargs,
174 reply_handler=reply_handler, 188 timeout=const_TIMEOUT,
175 error_handler=error_handler 189 reply_handler=reply_handler,
176 ) 190 error_handler=error_handler
191 )
192 except ValueError as e:
193 if e.args[0].startswith("Unable to guess signature"):
194 # same hack as for Bridge.__getattribute__
195 log.warning("using hack to work around inspection issue")
196 proxy = self.db_plugin_iface.proxy_object
197 IN_PROGRESS = proxy.INTROSPECT_STATE_INTROSPECT_IN_PROGRESS
198 proxy._introspect_state = IN_PROGRESS
199 proxy._Introspect()
200 self.db_plugin_iface.get_dbus_method(name)(
201 *args,
202 **kwargs,
203 timeout=const_TIMEOUT,
204 reply_handler=reply_handler,
205 error_handler=error_handler
206 )
207
208 else:
209 raise e
177 return fut 210 return fut
178 211
179 return getPluginMethod 212 return getPluginMethod
180 213
181 def bridgeConnect(self): 214 def bridgeConnect(self):