使用Twisted的异步WSGI

8 投票
2 回答
3965 浏览
提问于 2025-04-16 21:54

我正在为一个使用Twisted的应用程序构建一个网页界面,想用WSGI来实现,而不是直接使用twisted.web(因为我网站的其他部分都是WSGI,而且我已经有了不少WSGI的代码)。

我找到的关于WSGIResource的Twisted文档页面(http://twistedmatrix.com/documents/current/web/howto/web-in-60/wsgi.html)上写着:就像其他WSGI容器一样,你在WSGI应用中不能做任何异步操作,即使这是一个Twisted的WSGI容器。

这是真的吗?有没有什么不那么复杂的方法可以在WSGI中实现像twisted.web那样的异步网页请求处理呢?也许是作为其他开源项目的一部分?如果没有的话,我的计划是让WSGI线程在反应器线程中执行异步工作,并通过轮询来阻塞,直到数据可用。这听起来不太好。

如果在Twisted中有比较简单的方法来异步处理WSGI请求,我很想知道。

2 个回答

5

原则上,WSGI(Web服务器网关接口)并不是和异步程序设计相互排斥的;实际上,PEP 333 详细说明了服务器、应用程序和中间件应该如何运作,以支持这种设计。

这其中的关键是返回一个迭代器给容器。每当调用异步的 wsgi app_iter 时,它会检查所有待处理的异步任务(比如数据库连接等),如果有任务有数据可用,app_iter 就会返回一些数据;如果没有数据可用,它就返回一个空字符串。为了支持这一点,wsgi 容器需要跟踪所有正在进行的请求,并依次处理它们以获取更多数据,同时还要处理其他需要完成的工作。

实际上,很少有 wsgi 应用或框架真正做到这一点。几乎所有的 wsgi 框架都会因为各种原因而阻塞,比如从磁盘读取文件或从数据库加载数据(大多数 ORM(对象关系映射)让这个问题变得更复杂)。Twisted 的 wsgi 容器假设由于某些 wsgi 应用会阻塞,因此任何 wsgi 应用都有可能会阻塞,所以它总是将它们放在一个线程中运行。

你可以做两件事:要么探索 Twisted 自己的网络框架,它相对稳定;要么考虑在 Twisted 自己的容器之外为 wsgi 创建一个包装。确保 wsgi 应用实际上是异步的,当然是后者的前提条件,但 wsgi 本身其实很简单,只是一个薄薄的 http 包装,所以应该不难。

5

你为什么想用WSGI来做异步的事情呢?WSGI的好处在于,你可以把你的应用程序放在任何支持WSGI的容器上运行。如果你开始使用Twisted的API来做异步操作,那你就只能把应用程序放在Twisted的WSGI容器里了。

所以,你可能更应该直接使用Twisted Web,而不是通过WSGI来处理你的异步代码。

撰写回答