Closed
Description
🐞 Describe the bug
aiohttp.ClientTimeout.total is annotated to accept floats, yet my observations are that timeout condition is checked once a second. Is it a bug or feature? E.g. requests library does not have this limitation and easily works with 0.01 timeouts in my tests. I realize that sub-second timeouts are quite synthetic, but very useful for tests.
💡 To Reproduce
aiohttp 3.6.2 on Ubuntu 18.04 amd64 with CPython 3.8.3.
Consider the below code:
import asyncio
import socket
import sys
import time
import aiohttp
from aiohttp import web
async def hello(request):
await asyncio.sleep(10)
return web.Response(text="Hello, world")
async def run_client(port: int, timeout: float):
async with aiohttp.ClientSession() as session:
while True:
start = time.monotonic()
try:
await session.get(f"http://localhost:{port}/",
timeout=aiohttp.ClientTimeout(total=timeout))
except asyncio.TimeoutError:
pass
took = time.monotonic() - start
print(f"expected={timeout}, took={took:.3f}, skew={took-timeout:.3f}")
async def amain(timeout: float):
app = web.Application()
app.add_routes([web.get('/', hello)])
runner = web.AppRunner(app)
await runner.setup()
sock = socket.socket(socket.AF_INET, type=socket.SOCK_STREAM)
sock.bind(("localhost", 0))
_, port = sock.getsockname()
site = web.SockSite(runner=runner, sock=sock)
await site.start()
await run_client(port, timeout)
if __name__ == "__main__":
asyncio.run(amain(float(sys.argv[1])))No matter what the timeout value is, the actual timeout is always in multiples of 1 second as you can see in the took value below:
$ python /tmp/timeout-bug.py 0.1
expected=0.1, took=0.726, skew=0.626
expected=0.1, took=1.000, skew=0.900
expected=0.1, took=1.000, skew=0.900
python /tmp/timeout-bug.py 0.8
expected=0.8, took=1.414, skew=0.614
expected=0.8, took=0.999, skew=0.199
expected=0.8, took=1.000, skew=0.200
expected=0.8, took=1.001, skew=0.201
python /tmp/timeout-bug.py 1.1
expected=1.1, took=1.473, skew=0.373
expected=1.1, took=2.000, skew=0.900
expected=1.1, took=2.000, skew=0.900
expected=1.1, took=2.000, skew=0.900
python /tmp/timeout-bug.py 2.1
expected=2.1, took=2.158, skew=0.058
expected=2.1, took=2.999, skew=0.899
expected=2.1, took=3.001, skew=0.901
expected=2.1, took=2.998, skew=0.898
💡 Expected behavior
Is this intentional or a bug?
📋 **Your version of the Python**
<!-- Attach your version of the Python. -->
```console
$ python --version
Python 3.8.3
...
📋 Your version of the aiohttp/yarl/multidict distributions
$ python -m pip show aiohttp
Name: aiohttp
Version: 3.6.2
Summary: Async http client/server framework (asyncio)
Home-page: https://github.com/aio-libs/aiohttp
Author: Nikolay Kim
Author-email: fafhrd91@gmail.com
License: Apache 2
Location: /home/.../lib/python3.8/site-packages
Requires: multidict, chardet, async-timeout, attrs, yarl
Required-by: $ python -m pip show multidict
Name: aiohttp
Version: 3.6.2
Summary: Async http client/server framework (asyncio)
Home-page: https://github.com/aio-libs/aiohttp
Author: Nikolay Kim
Author-email: fafhrd91@gmail.com
License: Apache 2
Location: /home/.../lib/python3.8/site-packages
Requires: multidict, chardet, async-timeout, attrs, yarl
Required-by:
$ python -m pip show multidict
Name: multidict
Version: 4.7.6
Summary: multidict implementation
Home-page: https://github.com/aio-libs/multidict
Author: Andrew Svetlov
Author-email: andrew.svetlov@gmail.com
License: Apache 2
Location: /home/.../lib/python3.8/site-packages
Requires:
Required-by: yarl, aiohttp$ python -m pip show yarl
Name: yarl
Version: 1.4.2
Summary: Yet another URL library
Home-page: https://github.com/aio-libs/yarl/
Author: Andrew Svetlov
Author-email: andrew.svetlov@gmail.com
License: Apache 2
Location: /home/.../lib/python3.8/site-packages
Requires: idna, multidict
Required-by: aiohttp📋 Additional context