Реализация асинхронного метода в 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.

Я использую glib2 реактор Twisted.

Обновление: Я знаю, что это поведение возможно реализовать - DBus включает "сериал" (уникальный идентификатор) в вызовы метода, и вызываемый метод имеет доступ к этому идентификатору для соответствия "вызовам" "ответам".

5
задан jldupont 26 January 2010 в 20:26
поделиться

1 ответ

Я не пробовал, но чтение документации на dbus.service.method выявляет параметр async_callback. Похоже, что этот параметр используется для получения асинхронного результата. Например:

@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, который возвращает Deferred, то вы можете легко связать Deferred с этими обратными вызовами:

d.addCallbacks(callback, errback)

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

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

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

.
6
ответ дан 14 December 2019 в 13:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: