Реализация асинхронного метода в Python DBus - PullRequest
5 голосов
/ 26 января 2010

Как мне реализовать асинхронный метод в 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 включает в себя «последовательный» (уникальный идентификатор) для вызовов метода, и вызываемый метод имеет доступ к этому идентификатору для сопоставления «вызовов» "отвечает".

1 Ответ

6 голосов
/ 26 января 2010

Я не пробовал этого, но при чтении документации для 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")

Если вместо этого у вас есть API, который возвратил Отложенное, вы можете легко связать Отложенное с этими обратными вызовами:

d.addCallbacks(callback, errback)

Что касается корреляции между вызовом и ответом, я предполагаю, что вся обработка серийного номера скрыта внутри dbus.service.method. Я подозреваю, что функции callback и errback, которые передаются при использовании функции async_callbacks, являются экземплярами некоторого класса, который можно вызвать и который имеет серийный номер в качестве атрибута, или же определены как вложенные функции и закрываются по последовательному число. Таким образом, при вызове одного из них он может убедиться, что верное значение вернулось в соединение, чтобы связать ответ с исходным запросом.

Однако это лишь немного обоснованное предположение, основанное на вашем упоминании серийных номеров и моем опыте внедрения различных асинхронных систем. :) Чтение реализации dbus.service.method, вероятно, выявит реальную стратегию без особых проблем.

(Хорошо, я действительно пошел и посмотрел на реализацию сейчас, и, к сожалению, она довольно сложна, и я потерял след, когда он добрался до некоторого кода, который определен в привязках dbus уровня C, который немного сложнее чем Я заинтересован в этом. Я все еще подозреваю, что общая идея, которую я описал выше, верна, но детали реализации более сложны, чем я ожидал.)

...