我在Twisted中开发反向代理时遇到问题.它有效,但似乎过于复杂和复杂.这很像是伏都教.
网上或书中是否有任何简单,可靠的异步程序结构示例?一种最佳实践指南?当我完成我的程序时,我希望能够以某种方式看到结构,而不是看着一碗意大利面.
Twisted包含大量示例.其中一个特别是"手指的演变"教程,包含对异步程序如何从非常小的内核增长到具有大量移动部件的复杂系统的全面解释.您可能感兴趣的另一个是关于简单编写服务器的教程.
关于Twisted,甚至其他异步网络库(例如asyncore,MINA或ACE)的关键是,只有在发生某些事情时才会调用您的代码.我听过的那部分通常听起来像"伏都教"就是回调的管理:例如,Deferred
.如果您习惯于编写直线运行的代码,并且只调用立即返回结果的函数,那么等待某些东西给您回电的想法可能会令人困惑.但是没有什么神奇的,没有关于回调的"伏都教".在最低级别,反应堆只是坐在那里等待一小部分事情发生:
数据到达连接(它将调用dataReceived
协议)
时间已过(它将调用注册的函数callLater
).
已接受连接(它将buildProtocol
在注册了a 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!'
在像扭曲库的核心,在主回路的功能不是sleep
,但操作系统调用等select()
或poll()
,如由露出像模块Python的选择模块.我说"喜欢" select
,因为这是一个在平台之间变化很大的API,几乎每个GUI工具包都有自己的版本.Twisted目前为此主题提供了14种不同变体的抽象界面.这种API提供的常见问题是提供一种说法"这是我正在等待的事件列表.进入睡眠直到其中一个发生,然后醒来并告诉我它们是哪一个. "