У меня проблемы с разработкой обратного прокси в Twisted. Это работает, но кажется слишком сложным и запутанным. Так много в этом похоже на вуду.
Есть ли в Интернете или в книгах какие-либо примеры асинхронной структуры программы простой, прочный? Что-то вроде руководства по передовой практике? Когда я завершу свою программу, я хотел бы иметь возможность каким-то образом видеть структуру, а не смотреть на миску со спагетти.






Twisted содержит большое количество примеров. Один, в частности, учебник "эволюция пальца", содержит подробное объяснение того, как асинхронная программа растет от очень маленького ядра до сложной системы с множеством движущихся частей. Еще один, который может вас заинтересовать, - это учебник по простому пишущие серверы.
Ключевой момент, о котором следует помнить о Twisted или даже других асинхронных сетевых библиотеках (таких как асинкорный, MINA или ТУЗ), заключается в том, что ваш код вызывается только тогда, когда что-то происходит. Часть, которую я чаще всего слышал как «вуду», - это управление обратными вызовами: например, Deferred. Если вы привыкли писать код, который выполняется по прямой линии и вызывает только функции, которые немедленно возвращаются с результатами, идея ожидания чего-то, чтобы вам перезвонили, может сбивать с толку. Но в обратных звонках нет ничего волшебного, никакого «вуду». На самом нижнем уровне реактор просто сидит и ждет, когда произойдет одно из небольшого числа событий:
dataReceived по протоколу)callLater).buildProtocol на заводе, зарегистрированном с функцией listenXXX или connectXXX).connectionLost по соответствующему протоколу)Каждая асинхронная программа начинается с того, что подключает несколько из этих событий, а затем запускает реактор, чтобы дождаться, когда они произойдут. Конечно, происходящие события приводят к большему количеству событий, которые подключаются или отключаются, и поэтому ваша программа продолжает свой веселый путь. Помимо этого, в структуре асинхронной программы нет ничего особенного, интересного или особенного; обработчики событий и обратные вызовы - это просто объекты, и ваш код выполняется обычным образом.
Вот простой «движок, управляемый событиями», который показывает, насколько прост этот процесс.
# Engine
import time
class SimplestReactor(object):
def __init__(self):
self.events = []
self.stopped = False
def do(self, something):
self.events.append(something)
def run(self):
while not self.stopped:
time.sleep(0.1)
if self.events:
thisTurn = self.events.pop(0)
thisTurn()
def stop(self):
self.stopped = True
reactor = SimplestReactor()
# Application
def thing1():
print 'Doing thing 1'
reactor.do(thing2)
reactor.do(thing3)
def thing2():
print 'Doing thing 2'
def thing3():
print 'Doing thing 3: and stopping'
reactor.stop()
reactor.do(thing1)
print 'Running'
reactor.run()
print 'Done!'
В основе таких библиотек, как Twisted, функция в основном цикле - это не sleep, а вызов операционной системы, такой как select() или poll(), который предоставляется таким модулем, как модуль выбора Python. Я говорю «нравится» select, потому что это API, который сильно различается между платформами, и почти каждый инструментарий GUI имеет свою собственную версию. Twisted в настоящее время предоставляет абстрактный интерфейс для 14 различных вариаций этой темы. Обычно такой API предоставляет способ сказать: «Вот список событий, которых я жду. Засыпайте, пока не произойдет одно из них, затем проснитесь и скажите мне, какое из них это было. "
Надеюсь, вам повезло с twisted. В настоящее время это один из моих любимых фреймворков.