在Twisted中取消一组HTTP请求
我正在使用 twisted.web.client.getPage 发起多个 HTTP 请求,并希望能够根据用户的要求取消其中一些请求。理想情况下,我想做类似这样的事情:
# Pseudocode, getPage doesn't work like this:
getPage(url1, "group1")
getPage(url2, "group1")
getPage(url3, "group1")
...
# Later on
reactor.cancel_all("group1")
也许我可以把所有的 Deferreds 加到一个 DeferredList 中,但我有很多小请求,所以大部分请求在某个时间点都会完成(而且,我也不知道是否可以把 Deferreds 加到一个已经存在的 DeferredList 中)……有没有更合适的解决方案?
2 个回答
0
我这里不提供解决方案,而是想给大家指个方向,去看看在Twisted邮件列表上有个相关的讨论。
1
你提到的其实是两个不同的问题。首先,用 getPage
发出的 HTTP 请求能不能被取消?答案是不能。其次,能不能把多个操作放在一起,这样它们就可以同时被取消?当然可以,这其实并不复杂:
def cancel(group):
for job in group:
job.cancel()
group = []
group.append(job1)
group.append(job2)
...
cancel(group)
这里没有什么特别的关于 Twisted 的内容——这只是创建一个集合,然后对它进行操作。你不需要反应器来帮忙。你需要的是一种方法来取消单个操作。最新版本的 Twisted 增加了 Deferred.cancel
(所以,和 pyfunc 的回答中提到的旧帖子相反,Deferred 现在确实有取消的概念了)。不过,要让这个功能真正起作用,每个创建 Deferred 的 API——比如 getPage
——都需要更新,以执行相关的取消操作。截至 Twisted 10.1,getPage
还没有更新。
所以你可以选择为 getPage
实现取消功能(并把它贡献给 Twisted,拜托了!),或者你可以不去考虑实际取消 HTTP 请求,而是在结果到达时直接忽略它。