【问题标题】:How can I use Twisted's ThrottlingFactory with their web client?如何将 Twisted 的 ThrottlingFactory 与他们的 Web 客户端一起使用?
【发布时间】:2022-07-02 15:28:43
【问题描述】:

问题

我需要同时执行 HTTP 请求并模拟高延迟。我在 Python 中遇到了 Twisted 包,其中包括 HTTP clientThrottlingFactory。我遇到的问题是对于新手来说文档不清楚,而且我无法理解如何使用 HTTP 客户端在 API 调用中利用 ThrottlingFactory。

我目前正在使用以下示例代码进行测试。到目前为止没有任何效果。

from sys import argv
from pprint import pformat

from twisted.internet.task import react
from twisted.web.client import Agent, readBody
from twisted.web.http_headers import Headers


def cbRequest(response):
    print("Response version:", response.version)
    print("Response code:", response.code)
    print("Response phrase:", response.phrase)
    print("Response headers:")
    print(pformat(list(response.headers.getAllRawHeaders())))
    d = readBody(response)
    d.addCallback(cbBody)
    return d


def cbBody(body):
    print("Response body:")
    print(body)


def main(reactor, url=b"http://httpbin.org/get"):
    agent = Agent(reactor)
    d = agent.request(
        b"GET", url, Headers({"User-Agent": ["Twisted Web Client Example"]}), None
    )
    d.addCallback(cbRequest)
    return d


react(main, argv[1:])

如何在本例中使用 ThrottlingFactory?

【问题讨论】:

    标签: python twisted bandwidth-throttling


    【解决方案1】:

    你说得对 - 这个组合很尴尬,应该有更好的文档记录,并且可以说有更好的 API!

    不过,您可以通过在您的应用程序和 reactor 之间放置一个代理来完成此操作。

    看起来像这样:

    from sys import argv
    from pprint import pformat
    from dataclasses import dataclass
    
    
    from twisted.internet.task import react
    from twisted.internet.interfaces import IReactorTCP
    from twisted.web.client import Agent, readBody
    from twisted.web.http_headers import Headers
    from twisted.protocols.policies import ThrottlingFactory
    
    
    def cbRequest(response):
        print("Response version:", response.version)
        print("Response code:", response.code)
        print("Response phrase:", response.phrase)
        print("Response headers:")
        print(pformat(list(response.headers.getAllRawHeaders())))
        d = readBody(response)
        d.addCallback(cbBody)
        return d
    
    
    def cbBody(body):
        print("Response body:")
        print(len(body))
    
    
    @dataclass
    class SlowReactorProxy:
        original: IReactorTCP
    
        def __getattr__(self, name):
            return getattr(self.original, name)
    
        def connectTCP(self, host, port, factory, timeout=30, bindAddress=None):
            return self.original.connectTCP(
                host, port, ThrottlingFactory(factory, readLimit=0.1), timeout, bindAddress
            )
    
    
    def main(reactor, url=b"http://httpbin.org/bytes/10485760000"):
        agent = Agent(SlowReactorProxy(reactor))
        d = agent.request(
            b"GET", url, Headers({"User-Agent": ["Twisted Web Client Example"]}), None
        )
        d.addCallback(cbRequest)
        return d
    
    
    react(main, argv[1:])
    

    然而,不幸的是,ThrottlingFactory 的流量限制算法非常原始;只有一个每秒触发一次的计时器,如果消耗了太多数据,则暂停所有人。这意味着您将以最大速度阅读,一次整秒为零节流,然后,在用完该配额后,暂停相当长的一段时间。在我的(千兆位)网络上,我无法从 httpbin 中获得足够大的实体主体(最大大小似乎是 102400)以便生成数据超过一秒钟,因此在这种情况下不会发生任何限制.

    希望这将帮助您完成任务,但我鼓励您 file a bug on twisted 以使 HTTP 和限制的组合更加优雅和响应。

    【讨论】:

      猜你喜欢
      • 2015-04-22
      • 2019-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多