Можно ли использовать Perspective Broker через stdio вместо TCP?

Я использую Twisted Perspective Broker для RMI между процессом и подпроцессом.

Вместо прослушивания TCP-сокета (например, путем передачи reactor.listenTCP() экземпляра PBServerFactory) и подключения к нему подпроцесса, я бы предпочел использовать stdin и stdout подпроцесса.

Я нашел twisted.internet.stdio.StandardIO, но если это так, я не уверен, как все настроить.

Возможно ли использовать PB поверх stdio вместо TCP? Как?


Подожди, а почему?

Подпроцесс предназначен для запуска ненадежного кода. Он изолирован, но должен иметь возможность связываться с родительским процессом ограниченными способами. Некоторая форма RMI, безусловно, является самым чистым вариантом для конкретного случая использования, и у PB есть модель доступа, которая выглядит правильной. Но у изолированного процесса нет и не должно быть доступа к сети. Этот RMI является его единственным средством связи с внешним миром, и передача его через stdin / stdout кажется чистым способом ведения бизнеса.

Но если я поступлю неправильно, это тоже вполне верный ответ.


person Etaoin    schedule 20.05.2013    source источник


Ответы (1)


Использование протокола, такого как PB, между родительским и дочерним процессом через соединение, подобное stdio, состоит из двух частей. Одна часть находится в дочернем процессе и использует файловые дескрипторы 0 и 1 для связи с родительским процессом. Другая часть - это родительский процесс, использующий любые файловые дескрипторы, соответствующие дочерним 0 и 1.

StandardIO - это первая штука. Вам все еще нужен второй кусок - это IReactorProcess.spawnProcess.

Однако более новые API конечных точек - лучший способ получить доступ к этой функции.

Основы конечных точек заключаются в том, что конечная точка клиента позволяет вам подключаться к серверу, не заботясь о том, как именно установлено это соединение, а конечная точка сервера позволяет вам принимать подключения от клиентов, не заботясь о точности как эти клиенты подключаются.

Существует конечная точка клиента дочернего процесса и конечная точка сервера stdio. Это означает, что вы можете написать своему клиенту что-то вроде:

factory = PBClientFactory(...)
d = factory.getRootObject()
...

clientEndpoint.connect(factory)

И ваш сервер примерно так:

factory = PBServerFactory(...)
...
serverEndpoint.listen(factory)

И теперь у вас есть клиент и сервер, которые будут общаться друг с другом, но вы еще не указали, как они разговаривают друг с другом. Возможно, это TCP или, возможно, это stdio.

Тогда все, что вам нужно, это выбрать правильные конечные точки для использования. Чтобы придерживаться вашей идеи общения через stdio:

clientEndpoint = ProcessEndpoint(reactor, "/path/to/child", ("argv",), ...)
serverEndpoint = StandardIOEndpoint(reactor)

Если вы передумаете позже, то переключиться, скажем, на TCP так же просто, как:

clientEndpoint = TCP4ClientEndpoint(reactor, "1.2.3.4", 12345)
serverEndpoint = TCP4ServerEndpoint(reactor, 12345)

Или вы можете использовать механизм плагина для строковых описаний конечных точек, чтобы вместо этого преобразовать это в конфигурацию:

clientEndpoint = clientFromString(reactor, options["client-endpoint"])
serverEndpoint = serverFromString(reactor, options["server-endpoint"])

Где options["client-endpoint"] и options["server-endpoint"] - строки типа "tcp:host=1.2.3.4:port=12345" и "tcp:port=12345".

Для получения дополнительной информации см. полное руководство по конечным точкам.

person Jean-Paul Calderone    schedule 20.05.2013