Смешать Python Twisted с многопроцессорностью? - PullRequest
10 голосов
/ 19 апреля 2011

Мне нужно написать прокси-подобную программу на Python, рабочий процесс очень похож на веб-прокси. Программа находится между клиентом и сервером, принимает запросы, отправленные клиентом на сервер, обрабатывает запрос, а затем отправляет его на исходный сервер. Конечно, используемый протокол является частным протоколом, использующим TCP.

Чтобы свести к минимуму трудозатраты, я хочу использовать Python Twisted для обработки получения запроса (часть действует как сервер) и повторной отправки (часть действует как клиент).

Чтобы добиться максимальной производительности, я хочу использовать многопроцессорность Python (многопоточность имеет ограничение GIL), чтобы разделить программу на три части (процессы). Первый процесс запускает Twisted для получения запросов, помещения запроса в очередь и немедленного возврата успеха исходному клиенту. Второй процесс берет запрос из очереди, обрабатывает запрос дальше и помещает его в другую очередь. 3-й процесс берет запрос из 2-й очереди и отправляет его на исходный сервер.

Я был новичком в Python Twisted, я знаю, что он основан на событиях, я также слышал, что лучше не смешивать Twisted с многопоточностью или многопроцессорностью. Так что я не знаю, подходит ли этот способ или есть более элегантный способ с использованием Twisted?

Ответы [ 3 ]

18 голосов
/ 19 апреля 2011

Twisted имеет свой собственный управляемый событиями способ запуска подпроцессов, который (по моему скромному, но правильному мнению) лучше, чем модуль multiprocessing. Основным API является spawnProcess , но такие инструменты, как ампула , предоставляют надстройки более высокого уровня.

Если вы используете spawnProcess, вы сможете обрабатывать выходные данные из подпроцессов так же, как и любое другое событие в Twisted; если вы используете multiprocessing, вам нужно будет разработать свой собственный способ на основе очереди для вывода вывода из подпроцесса в Twisted mainloop, поскольку обычный callFromThread API, который поток может использовать, выиграл не работает из другого процесса. В зависимости от того, как вы это называете, он либо попытается травить реактор, либо просто использует другой нерабочий реактор в подпроцессе; в любом случае он потеряет ваш звонок навсегда.

4 голосов
/ 19 апреля 2011

ampoule - первое, что я думаю, когда читаю ваш вопрос.

Это простая реализация пула процессов, использующая протокол AMP для связи. Вы можете использовать функцию deferToAMPProcess, она очень проста в использовании.

0 голосов
/ 22 апреля 2011

Вы можете попробовать что-то вроде техники кооперативной многозадачности, как описано там http://us.pycon.org/2010/conference/schedule/event/73/.Это похоже на технику, о которой говорил Глиф, и стоит попробовать.

Вы можете попробовать использовать ZeroMQ с Twisted, но пока это действительно сложно и экспериментально:)

...