Блокировка звонков Thrift с помощью Twisted - PullRequest
1 голос
/ 19 октября 2011

У меня есть сервер Twisted / Thrift, использующий протокол TTwisted.Я хочу, чтобы соединения от клиентов оставались открытыми до тех пор, пока не произойдет определенное событие (об этом уведомляет Twisted реактор с помощью обратного вызова).

class ServiceHandler(object):
    interface.implements(Service.Iface)

    def listenForEvent(self):
        """
        A method defined in my Thrift interface that should block the Thrift
        response until my event of interest occurs.
        """
        # I need to somehow return immediately to free up the reactor thread,
        # but I don't want the Thrift call to be considered completed. The current
        # request needs to be marked as "waiting" somehow.

    def handleEvent(self):
        """
        A method called when the event of interest occurs. It is a callback method
        registered with the Twisted reactor.
        """
        # Find all the "waiting" requests and notify them that the event occurred.
        # This will cause all of the Thrift requests to complete.

Как быстро вернуться из метода объекта моего обработчикасохраняя иллюзию блокирующего вызова Thrift?


Я инициализирую обработчик Thrift из запуска запуска Twisted:

def on_startup():
    handler = ServiceHandler()                      
    processor = Service.Processor(handler)                                   
    server = TTwisted.ThriftServerFactory(processor=processor,                  
        iprot_factory=TBinaryProtocol.TBinaryProtocolFactory())                 
    reactor.listenTCP(9160, server)

Мой клиент в PHP соединяется с:

  $socket = new TSocket('localhost', 9160);
  $transport = new TFramedTransport($socket);
  $protocol = new TBinaryProtocol($transport);
  $client = new ServiceClient($protocol);
  $transport->open();
  $client->listenForEvent();

Этот последний вызов ($client->listenForEvent()) успешно переходит на сервер и запускает ServiceHandler.listenForEvent, но даже когда этот метод сервера возвращает экземпляр twisted.internet.defer.Deferred(), клиент немедленно получает пустой массив, и я получаюисключение:

исключение 'TTransportException' с сообщением 'TSocket: истекло время ожидания чтения 4 байтов с локального хоста: 9160 на локальный порт 38395'

Ответы [ 2 ]

2 голосов
/ 19 октября 2011

Вы должны иметь возможность вернуть отложенное с listenForEvent.Позже handleEvent должен запустить, который возвратил Deferred (или те, которые вернули Deferreds), чтобы фактически сгенерировать ответ.

1 голос
/ 20 октября 2011

Ошибка, которую вы видите, указывает на то, что транспорт не создан (Twisted нуждается в этом, чтобы он мог заранее знать длину каждого сообщения).Кроме того, серверы Thrift поддерживают возврат отложенных от обработчиков, что еще более странно.Вы пытались вернуть defer.succeed («некоторое значение») и посмотреть, действительно ли работают deferreds?Затем вы можете перейти к этому, чтобы убедиться, что он полностью работает:

    d = defer.Deferred()
    reactor.callLater(0, d.callback, results)
    return d
...