是这个的总结了:http://wiki.jikexueyuan.com/project/twisted-intro/p01.html
1.twisted理论基础
问题:同步框架响应I/O时间慢
解决:异步事件驱动框架
就是讲事件驱动的理论基础,没什么说的
2.异步编程模式与Reactor初探
问题: 异步框架都需要有什么东西?
解决如下:
异步框架需要做到的东西:
- 处理所有不同系统会出现的I/O事件
- 提供优雅的抽象来帮助你在使用时少花些心思去考虑它的存在
- 提供可以在抽象层外使用的公共协议实现
twisted提供的就是reactor模式
3.初识Twisted
twisted的基础用法
4.由twisted支持的客户端
问题:twisted的整体组织是怎样的?
解决:通过大量接口去定义规范。
从twisted底层开始讲起,非常有必要去看看twisted.internet.interfaces
模块,很有用。写这么多接口一是为了文档化,而是为了结构化,更好的组织整个框架。twisted里边高层次的抽象大部分都是基于低层次的接口,twisted.internet.interfaces
模块提供了很多低层次的接口规范。
5.由Twisted扶持的客户端
问题:twisted的基本概念
解决:transport, protocol, protocol factory
twisted三大概念:
- transport: 表示一个TCP连接,每个客户端连进来都会有一个transport跟它对应。
- protocol: 表示连接上的协议,收到的数据应该怎么处理,实际上就是协议所要做的事情了。
- protocol factory: 产生协议的工厂,监听一个端口的话,每连进来一个客户端,就会生成一个协议实例,每个协议实例会指向一个transport实例,而protocol facotry就是管理所有这些连接的地方。
6.更加”抽象”的运用Twisted
问题:如何组织一个异步处理函数
解决:回调
将我们需要的功能封装成一个函数get_poetry(),这里的关键是回调,其实异步框架最主要的概念之一就是回调。还说了一些如何twisted中错误的基础处理方法,后边会提到正规的处理方法。
7.小插曲 Deferred
问题:如何组织很多回调?
解决:defer
用defer组建回调链。defer其实就是关于方便组织回调的一种抽象方式。异步事件处理中最常遇到的问题是我如何去获取、处理一个异步函数func()
的结果。我不可能直接用data = func()
来获取,只能用回调func(cb1())
,当func()完成时,它自己知道什么时候去调用cb1()
函数;但有时候我还想在cb1()
处理一遍结果之后,再接着处理cb1()
的结果,正常来说是在最开始调用func()
的时候接着嵌套一个回调,比如这样func(cb1(cb2()))
,放在cb2()
里边是因为只有cb1()
才知道什么时候应该去调用cb2()
;当前还可能有更多回调。。。。这就组成了一个回调链。twisted就提供了这样一种机制,把cb1()
,cb2()
或者还有cb3()
等等给串起来,在这条链的执行过程中,不是由这些回调自己去管理如何从一个函数切换到另一个函数,而是由twisted管理什么时候该切换去执行哪个函数,这种机制就是defer。当然上边说的只是正常的回调,在这些回调过程中任何一个环节都可能发生错误,也需要defer去组织如何处理错误的回调。错误回调就不说了,看那个回调的执行图就可以了。
8.使用Deferred的诗歌下载客户端
上一节是理论,这一节是实践
9.第二个小插曲,deferred
问题:defer是如何同时管理正常的回调和错误回调的,如何去切换执行在回调链上的各个函数的?
解决:第7节给的那个图。
向defer中添加回调时是按照回调对儿添加的,一次添加两个:正常回调cb():callback,错误回调eb():errback。对某一层回调,不管上层调用的是cb()还是eb(),上层正常,这一次层就调用cb();上层产生错误,这一次层就调用eb()。依次往后。
10.增强defer功能的客户端
更详细的讲了上一节我总结的流程。defer回调链路由
11.改进诗歌下载服务器
问题:如何管理服务器的多个tcp连接?
解决:Transport、Protocol、Protocol Factory
第5节三大概念的实践
12.改进诗歌下载服务器
问题:如何处理收到的数据,如何去组织这个处理过程?
解决:基于Protocol的一些协议实现
twisted自带的一些Protocol的实现
13.使用Deferred新功能实现新客户端
问题:在代码中如何去组织defer
解决:通常情况下,一个对象创建了一个deferred,那么它应当负责激活它
14.Deferred用于同步环境
问题:一个函数可能实时返回结果,也可能返回一个defer,如何实现?
解决:使用maybeDeferred()函数,返回一个激活了的defer。
利用的是激活的defer也可以再添加回调函数,方便后续去处理。
15.测试诗歌
代码测试
16.Twisted 进程守护
守护进程一类的辅助框架
17.构造”回调”的另一种方法
问题:回调链会很长很长,每次回调都要去定义一个函数来实现,这种阅读、重构起来会很麻烦。
解决:使用inlineCallbacks。
回调链相当于在一个时间点上横向去延展处理逻辑,但我们通常的理解方式是纵向的、从上到下的去理解,那defer组织的回调就不自然(当然理解之后也就那样)。twisted提供了纵向组织回调的方法,也就是inlineCallbacks,需要结合yield。
18.Deferreds 全貌
问题:一个程序里边可能有很多defer,如何管理他们?
解决:用DeferredList
DeferredList也可以用defer控制,添加回调等
19.取消之前的意图
问题:一个defer启动回调,我们忽然又不想要这个结果了,怎么办?
解决:defer.cancel()
这里取消并不是取消那个处理过程,而是不要结果的意思。比如说我在defer中添加了回调cb(),defer激活之后,就会运行下去,在cb执行之前,我调用了cancel(),并不是说cb()不执行了,它还会执行,只是结果我们就不需要了。实际取消一个回调链,可能还需要执行一些其他动作,比如关闭网络连接,回滚数据库事务,结束子进程等,在创建defer的时候,还是用回调去实现这种处理,d = Deferred(canceller()),就可以在defer.cancel()的时候实际去执行这些操作。
剩下的三章就不去说了。总之,twisted提供了一个异步处理框架,这个框架提供了三个基本概念: transport, protocol, protocol factory
, 提供了两个组织回调的工具:defer, inlineCallbacks
,————最主要的也就是这两个部分了,其他的就按需要再去学习了。
最后想说的是,在刚开始学的时候还是很难理解,但理解了之后就发现异步框架也就是这样,twisted是这样,tornado也是这样,然后你去看nginx代码,发现也是这样。顺便提一下,读nginx代码,就像是同时看一个twisted源码跟它之上的一个应用,是一个套路的。