我有一个网络服务器,大致如下:
async def websocket_handler(request):
ws = web.WebSocketResponse()
await ws.prepare(request)
# ==========================================
cards = []
async for msg in ws:
if msg.type == aiohttp.WSMsgType.TEXT:
Q = json.loads(msg.data)
if "q" in Q:
async with aiohttp.ClientSession(cookies=request.cookies) as session:
async with session.get(f"{SEARCH_ROOT}/s", params=Q) as resp:
doc_order = await resp.json()
cards = [
*doc_order["results"],
{"done": True},
]
if len(cards) > 0:
card = cards.pop(0)
await ws.send_json(card)
else:
ws.close()
return ws
问题是,这工作得很好,但在大约 13-15 个新的 websocket 连接之后,我开始看到错误,声称could not start a new thread
.
文档提到每个服务器实例的客户端会话应该存在一次 https://aiohttp.readthedocs.io/en/stable/faq.html#how-do-i-manage-a-clientsession-within-a-web-server但我不知道该怎么做。我有一些想法:
- 我只创建一个全局会话对象吗?
- 我是否必须以某种方式使用后台任务 https://docs.aiohttp.org/en/stable/web_advanced.html#background-tasks
我得到的确切回溯是这样的:
Traceback (most recent call last): [58/1849]
File "/home/user/.local/share/virtualenvs/myproject/lib/python3.6/site-packages/aiohttp/web_protocol.py", line 418, in start
resp = await task
File "/home/user/.local/share/virtualenvs/myproject/lib/python3.6/site-packages/aiohttp/web_app.py", line 458, in _handle
resp = await handler(request)
File "/home/user/myproject/myproject/api/websocket.py", line 22, in websocket_handler
async with aiohttp.request('GET', f"{SEARCH_ROOT}/s", params=Q, cookies=request.cookies) as resp:
File "/home/user/.local/share/virtualenvs/myproject/lib/python3.6/site-packages/aiohttp/client.py", line 1043, in __aenter__
self._resp = await self._coro
File "/home/user/.local/share/virtualenvs/myproject/lib/python3.6/site-packages/aiohttp/client.py", line 476, in _request
timeout=real_timeout
File "/home/user/.local/share/virtualenvs/myproject/lib/python3.6/site-packages/aiohttp/connector.py", line 522, in connect
proto = await self._create_connection(req, traces, timeout)
File "/home/user/.local/share/virtualenvs/myproject/lib/python3.6/site-packages/aiohttp/connector.py", line 854, in _create_connec
tion
req, traces, timeout)
File "/home/user/.local/share/virtualenvs/myproject/lib/python3.6/site-packages/aiohttp/connector.py", line 955, in _create_direct
_connection
traces=traces), loop=self._loop)
File "/home/user/.local/share/virtualenvs/myproject/lib/python3.6/site-packages/aiohttp/connector.py", line 825, in _resolve_host
self._resolver.resolve(host, port, family=self._family)
File "/home/user/.local/share/virtualenvs/myproject/lib/python3.6/site-packages/aiohttp/resolver.py", line 30, in resolve
host, port, type=socket.SOCK_STREAM, family=family)
File "/usr/lib/python3.6/asyncio/base_events.py", line 681, in getaddrinfo
host, port, family, type, proto, flags)
File "/usr/lib/python3.6/asyncio/base_events.py", line 644, in run_in_executor
return futures.wrap_future(executor.submit(func, *args), loop=self)
File "/usr/lib/python3.6/concurrent/futures/thread.py", line 123, in submit
self._adjust_thread_count()
File "/usr/lib/python3.6/concurrent/futures/thread.py", line 142, in _adjust_thread_count
t.start()
File "/usr/lib/python3.6/threading.py", line 846, in start
_start_new_thread(self._bootstrap, ())
RuntimeError: can't start new thread
Unhandled exception
Traceback (most recent call last):
File "/home/user/.local/share/virtualenvs/myproject/lib/python3.6/site-packages/aiohttp/web_protocol.py", line 447, in start
await resp.prepare(request)
File "/home/user/.local/share/virtualenvs/myproject/lib/python3.6/site-packages/aiohttp/web_response.py", line 353, in prepare
return await self._start(request)
File "/home/user/.local/share/virtualenvs/myproject/lib/python3.6/site-packages/aiohttp/web_response.py", line 667, in _start
return await super()._start(request)
File "/home/user/.local/share/virtualenvs/myproject/lib/python3.6/site-packages/aiohttp/web_response.py", line 410, in _start
await writer.write_headers(status_line, headers)
File "/home/user/.local/share/virtualenvs/myproject/lib/python3.6/site-packages/aiohttp/http_writer.py", line 112, in write_header
s
self._write(buf)
File "/home/user/.local/share/virtualenvs/myproject/lib/python3.6/site-packages/aiohttp/http_writer.py", line 67, in _write
raise ConnectionResetError('Cannot write to closing transport')
ConnectionResetError: Cannot write to closing transport