简体   繁体   English

SSL 传输上的 Asyncio 致命错误 - IndexError Deque Index Out Of Range

[英]Asyncio Fatal Error on SSL Transport - IndexError Deque Index Out Of Range

I keep running into the bellow error and can't work out how to fix it or whether it is a bug in asyncio that I need to report.我一直遇到以下错误,无法解决如何修复它,或者它是否是我需要报告的asyncio中的错误。 My program works fine is it basically the same as the example in there docs but it can send lots of messages upto 20 per second to multiple clients when there is a low number of updates it works fine but when the number of writes increases I run into this error.我的程序工作正常,它与文档中的示例基本相同,但是当更新数量较少时,它可以向多个客户端发送高达每秒 20 条的消息,但当写入次数增加时,我遇到了这个错误。

I am using create_server from asyncio to make the server listen for new clients and I believe this creates a new connection on each connection.我正在使用来自 asyncio 的create_server来让服务器监听新客户端,我相信这会在每个连接上创建一个新连接。 Not all clients stop only one clients stops and the rest keep running it's usually the last client that connected but not always.并非所有客户端都停止,只有一个客户端停止,其余客户端继续运行,通常是最后一个连接的客户端,但并非总是如此。 I have played with the asyncio/sslproto.py file removing the reference to [0] and replacing them with popleft which they got me the not very helpful SSL: BAD_LENGTH error which I have had before and using asyncio was supposed to be the fix.我玩过asyncio/sslproto.py文件,删除了对[0]的引用并用popleft替换它们,这让我得到了不太有用的SSL: BAD_LENGTH错误,我以前遇到过并且使用 asyncio 应该是修复。

When I logged the value of self._write_backlog it returned the deque as expected and before the error there was clearly data in it and I believe that self._write_backlog[0] should return the leftmost element in the deque which there appeared to be one.当我记录self._write_backlog的值时,它按预期返回了双端队列,并且在错误之前明显有数据,我相信self._write_backlog[0]应该返回双端队列中似乎有一个的最左边的元素。

Fatal error on SSL transport
protocol: <asyncio.sslproto.SSLProtocol object at 0x7f267462e780>
transport: <_SelectorSocketTransport fd=38 read=polling write=<idle, bufsize=0>>
Traceback (most recent call last):
    File "/usr/local/lib/python3.7/asyncio/sslproto.py", line 689, in 
    _process_write_backlog
  del self._write_backlog[0]
IndexError: deque index out of range

On further investigation the same error also seems to happen at a diffrent point in the code but it is the same error like it's trying to access an empty deque.在进一步调查中,同样的错误似乎也发生在代码的不同点,但它是同样的错误,就像它试图访问一个空的双端队列一样。

Fatal error on SSL transport
protocol: <asyncio.sslproto.SSLProtocol object at 0x7f45f802ec88>
transport: <_SelectorSocketTransport fd=29 read=polling write=<idle, bufsize=0>>
Traceback (most recent call last):
    File "/usr/local/lib/python3.7/asyncio/sslproto.py", line 664, in _process_write_backlog
    data, offset = self._write_backlog[0]
IndexError: deque index out of range

EDIT编辑

The version of python I am running on is 3.7.1 but I have also tried 3.7.3 which gave the same error.我正在运行的 python 版本是 3.7.1,但我也尝试过 3.7.3,它给出了同样的错误。

UPDATE更新

It is believed that this issue is caused by an incompatibility between asyncio and OpenSSL https://bugs.python.org/issue37226相信这个问题是由 asyncio 和 OpenSSL https://bugs.python.org/issue37226之间的不兼容引起的

UPDATE 2更新 2

A minimal example is available on GitHub GitHub 上提供了一个最小示例

The problem here is related to system resources when you connect lots of clients it can cause CPU or Memory to become exhausted which then causes this error as the write fails.这里的问题与系统资源有关,当您连接大量客户端时,它可能导致 CPU 或内存耗尽,然后在写入失败时导致此错误。

The solution is to implement flow control to limit the amount of data being sent at one time and stop resources becoming exhausted the following article has a good example of simple flow control that blocks while old data is removed then resumes using the high and low water marks.解决方案是实施流量控制以限制一次发送的数据量并防止资源耗尽以下文章有一个很好的简单流量控制示例,即在删除旧数据时阻塞,然后使用高水位线和低水位线恢复. When the data exceeds the high water mark it triggers pause_writing then when the data size reduces to lower than the low water mark writing resumes this can cause a noticeable slow down dependent on load.当数据超过高水位线时,它会触发 pause_writing,然后当数据大小减小到低于低水位线时,写入恢复,这可能会导致明显的减速,具体取决于负载。

As an alternative to adding your own flow control to a protocol the asyncio Streams primitives offer a simple way to write and read data that includes flow control by default but for me made implementation harder so I opted to include my own at the protocol level as shown in the linked article.作为将您自己的流控制添加到协议的替代方案,asyncio Streams 原语提供了一种简单的方法来写入和读取默认情况下包含流控制的数据,但对我而言,实现起来更加困难,因此我选择在协议级别包含我自己的,如图所示在链接的文章中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM