Mix Python Twisted с многопроцессорной обработкой?

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

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

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

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

Ответ 1

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

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

Ответ 2

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

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

Ответ 3

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

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