在Twisted中取消一组HTTP请求

1 投票
2 回答
505 浏览
提问于 2025-04-16 05:01

我正在使用 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 请求,而是在结果到达时直接忽略它。

撰写回答