Python DBus 中异步方法的实现
如何在 Python DBus 中实现异步方法?下面的例子:
class LastfmApi(dbus.service.Object):
def __init__(self):
bus_name = dbus.service.BusName('fm.lastfm.api', bus=dbus.SessionBus())
dbus.service.Object.__init__(self, bus_name, '/')
@dbus.service.method('fm.last.api.account', out_signature="s")
def getUsername(self):
## How do I get this method done asynchronously ??
## For example, this method should go off and retrieve the "username"
## asynchronously. When this method returns, the "username" isn't available
## immediately but will be made available at a later time.
我正在使用 Twisted 的 glib2 反应器。
更新:我知道这种行为是可以实现的 - DBus 包含方法调用的“序列”(唯一标识符),并且被调用的方法可以访问此标识符,以便将“调用”与“回复”相匹配”。
How do I implement an async method in Python DBus? An Example below:
class LastfmApi(dbus.service.Object):
def __init__(self):
bus_name = dbus.service.BusName('fm.lastfm.api', bus=dbus.SessionBus())
dbus.service.Object.__init__(self, bus_name, '/')
@dbus.service.method('fm.last.api.account', out_signature="s")
def getUsername(self):
## How do I get this method done asynchronously ??
## For example, this method should go off and retrieve the "username"
## asynchronously. When this method returns, the "username" isn't available
## immediately but will be made available at a later time.
I am using Twisted's glib2 reactor.
Update: I know this behavior is possible to implement - DBus includes a "serial" (unique identifier) to method calls and the called method has access to this identifier in order to match "calls" with "replies".
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我还没有尝试过这个,但是阅读 dbus.service.method 的文档揭示了 async_callbacks 参数。听起来像是使用此参数来提供异步结果。例如:
如果您有一个返回 Deferred 的 API,那么您可以轻松地将 Deferred 与这些回调关联起来:
就调用和响应之间的相关性而言,我假设所有序列号处理都隐藏在 <代码>dbus.service.method。我怀疑当您使用 async_callbacks 功能时传入的回调和 errback 函数要么是某个可调用且具有序列号作为属性的类的实例,要么被定义为嵌套函数并关闭序列号。这样,当您调用其中一个时,它们可以确保将正确的值传递回连接,以将响应与原始请求相关联。
然而,这只是根据您提到的序列号和我实现各种异步系统的经验而进行的稍微有根据的猜测。 :) 阅读 dbus.service.method 的实现可能会揭示实际的策略,而不会造成太大的痛苦。
(好吧,我现在实际上去查看了实现,不幸的是它相当复杂,当它到达 C 级 dbus 绑定中定义的一些代码时我丢失了踪迹,这比我更深入地挖掘我仍然怀疑我上面描述的总体想法是正确的,但实现的细节比我预期的要复杂。)
I haven't tried this, but reading the documentation for
dbus.service.method
reveals theasync_callbacks
parameter. It sounds like one uses this parameter to provide an asynchronous result. For example:If, instead, you have an API which returned a Deferred, then you can easily associate the Deferred with these callbacks:
As far as the correlation between call and response goes, I assume that all the serial number handling is hidden inside
dbus.service.method
. I suspect that the callback and errback functions that are passed in when you use theasync_callbacks
feature are either instances of some class which is callable and has the serial number as an attribute, or else are defined as nested functions and close over the serial number. This way, when you call one of them, they can make sure to pass the right value back to the connection to associate the response with the original request.However, that's just a slightly educated guess based on your mention of serial numbers and my experience with implementing various async systems. :) A read of the implementation of
dbus.service.method
would probably reveal the actual strategy without too much pain.(Okay, I actually went and looked at the implementation now, and unfortunately it's rather complicated, and I lost the trail when it got to some code that's defined in the C-level dbus bindings, which is a bit more digging than I'm interested in doing. I still suspect the general idea I described above is correct, but the details of the implementation are more involved than I expected.)