Python DBus 中异步方法的实现

发布于 2024-08-19 03:02:49 字数 788 浏览 6 评论 0原文

如何在 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

ㄖ落Θ余辉 2024-08-26 03:02:49

我还没有尝试过这个,但是阅读 dbus.service.method 的文档揭示了 async_callbacks 参数。听起来像是使用此参数来提供异步结果。例如:

@dbus.service.method('fm.last.api.account', out_signature="s",
                     async_callbacks=("callback", "errback"))
def getUsername(self, callback, errback):
    reactor.callLater(3, callback, "alice")

如果您有一个返回 Deferred 的 API,那么您可以轻松地将 Deferred 与这些回调关联起来:

d.addCallbacks(callback, errback)

就调用和响应之间的相关性而言,我假设所有序列号处理都隐藏在 <代码>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 the async_callbacks parameter. It sounds like one uses this parameter to provide an asynchronous result. For example:

@dbus.service.method('fm.last.api.account', out_signature="s",
                     async_callbacks=("callback", "errback"))
def getUsername(self, callback, errback):
    reactor.callLater(3, callback, "alice")

If, instead, you have an API which returned a Deferred, then you can easily associate the Deferred with these callbacks:

d.addCallbacks(callback, errback)

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 the async_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.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文