我在Twisted中开发反向代理时遇到问题。 它可以工作,但是似乎过于复杂和令人费解。 感觉很多像伏都教。
Web或书籍中是否有任何简单,可靠的异步程序结构示例? 一种最佳做法指南? 当我完成程序后,我希望仍然能够以某种方式看到结构,而不是看一碗意大利面。
Twisted包含大量示例。特别是"手指的进化"教程,其中包含对异步程序如何从很小的内核发展为具有许多活动部件的复杂系统的详尽解释。您可能感兴趣的另一个是有关简单编写服务器的教程。
关于Twisted甚至其他异步网络库(例如asyncore,MINA或ACE),要记住的关键是,只有在发生某些情况时才调用代码。我最常听到的听起来像是" voodoo"的部分是回调的管理:例如Deferred。如果您习惯编写直线运行的代码,并且只调用会立即返回结果的函数,那么等待某些东西来回调您的想法可能会令人困惑。但是,没有什么神奇的东西,也没有关于回调的"伏都教"。在最低级别,反应堆只是围坐在一旁,等待着少数事情之一发生:
数据到达连接(它将在协议上调用dataReceived)
时间已过去(它将调用在callLater中注册的函数)。
已接受连接(它将在注册了listenXXX或connectXXX功能的工厂上调用buildProtocol)。
连接已断开(它将在适当的协议上调用connectionLost)
每个异步程序都首先连接这些事件中的一些,然后启动反应堆以等待它们发生。当然,发生的事件会导致更多事件被挂断或断开连接,因此您的程序将继续进行下去。除此之外,关于异步程序结构,没有什么有趣或特别之处。事件处理程序和回调只是对象,并且您的代码以通常的方式运行。
这是一个简单的"事件驱动引擎",向您显示了此过程的简单程度。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| # 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模块之类的模块公开。我说" like" select,因为这是一个API,在不同平台之间差异很大,并且几乎每个GUI工具包都有其自己的版本。 Twisted当前为该主题的14个不同变体提供了抽象界面。此类API提供的常见功能是提供一种说法:"这是我正在等待的事件列表。进入睡眠状态直到其中一个发生,然后醒来并告诉我是哪个。"