Reputation: 73
The tracker often receives an error that I have not been able to fix and reproduce for a long time.
This is what my client looks like
class Client:
_auth = (API_USER, API_PASSWORD)
def __init__(self):
self.auth = aiohttp.BasicAuth(self._auth[0], self._auth[1])
async def send(self, url, json, debug=True,):
try:
async with aiohttp.ClientSession(
connector=aiohttp.TCPConnector(verify_ssl=False),
raise_for_status=True,
) as session:
async with session.post(
url=url,
json=json,
auth=self.auth,
) as response:
if debug:
print(f"{url} response.status", response.status, json)
if response.status not in [200, 201]:
error = False
result = None
return error, result
error = False
result = await response.json(content_type=None)
if 'error' in result:
if debug:
print(f'{url} error', result, json)
error = True
result = None
return error, result
except (
aiohttp.client_exceptions.ClientResponseError,
aiohttp.client_exceptions.ClientConnectorError,
JSONDecodeError,
TimeoutError,
) as e:
error = True
result = None
return error, result
Client.send(
url="my_url",
json=my_json
)
Please tell me what the problem is
To Reproduce: Do not know how
Expected behavior: Send request normally
Logs/tracebacks:
ConnectionResetError: Cannot write to closing transport
...
File "aiohttp/http_writer.py", line 67, in _write
raise ConnectionResetError('Cannot write to closing transport')
ClientOSError: [Errno None] Can not write request body for <my_url>
...
File "aiohttp/streams.py", line 588, in read
await self._waiter
Upvotes: 4
Views: 1562
Reputation: 124
I have solved my problem by creating A new Session. Before, I initialize a Session in the class, and then use it to make plenty of POST requests, I can find this "[Errno None] Can not write request body xxx" occasionally in log file. Thus, I think we should create a new Session on each request, and close it after getting the response.
# before
class TestClient():
def __init__(self):
self.a_url = 'http://127.0.0.1:22091/test1'
self.b_url = 'http://127.0.0.1:22092/test2'
self.c_url = 'http://127.0.0.1:22093/test3'
new_loop = asyncio.new_event_loop()
asyncio.set_event_loop(new_loop)
self.loop = asyncio.get_event_loop()
self.session = self.loop.run_until_complete(self.get_session())
async def get_session(self):
return aiohttp.ClientSession(read_timeout=2)
def __del__(self):
self.loop.close()
async def async_single_call(self):
async_time_out = 10
try:
task_list = [
asyncio.ensure_future(async_down(self.session, self.a_url, {'msg': "hello"*100000}, async_time_out)),
asyncio.ensure_future(async_down(self.session, self.b_url, {'msg': "hello"*100000}, async_time_out)),
asyncio.ensure_future(async_down(self.session, self.c_url, {'msg': "hello"*100000}, async_time_out))]
except Exception as e:
print(e)
finally:
pass
# after
class TestClient():
def __init__(self):
self.a_url = 'http://127.0.0.1:22091/test1'
self.b_url = 'http://127.0.0.1:22092/test2'
self.c_url = 'http://127.0.0.1:22093/test3'
new_loop = asyncio.new_event_loop()
asyncio.set_event_loop(new_loop)
self.loop = asyncio.get_event_loop()
def get_session(self):
return aiohttp.ClientSession(read_timeout=2)
def __del__(self):
self.loop.close()
async def async_single_call(self):
async_time_out = 10
the_new_session = self.get_session()
try:
task_list = [
asyncio.ensure_future(async_down(the_new_session, self.a_url, {'msg': "hello"*100000}, async_time_out)),
asyncio.ensure_future(async_down(the_new_session, self.b_url, {'msg': "hello"*100000}, async_time_out)),
asyncio.ensure_future(async_down(the_new_session, self.c_url, {'msg': "hello"*100000}, async_time_out))]
except Exception as e:
print(e)
finally:
await the_new_session.close()
I hope it can bring you some inspiration :-)
Upvotes: 1