Ketok4321 / speedtest

A graphical librespeed client written using gtk4 + libadwaita
GNU General Public License v3.0
27 stars 13 forks source link

With aiohttp 3.9.x and newer, frequent Python tracebacks during benchmark cause upload speed measurement to be incorrect #37

Open nekohayo opened 6 days ago

nekohayo commented 6 days ago

I don't know if this is something you will want to consider, but reporting it separately just in case, and because I doubt that this is the cause of the performance problem seen in #29…

I have now isolated the conditions under which the tracebacks can be encountered. In my case, it only happens when running the non-flatpak version, such as the 1.3.0 package available in Fedora 39 (whereas @yochananmarqos encountered the issue on Arch Linux instead), even if that's the app version number as the flatpak version.

Beyond the Python tracebacks, the symptoms are that the upload speed will be reproducibly much lower than reality, even compared to LibreSpeed's website, because the upload speed measurement will "start" at the correct speed (~60-70 mbps) and then gradually go down towards zero (in my case, 10mbps) as the tracebacks occur:

Screenshot from 2024-07-03 11-06-32

…when running the flatpak version of the app instead, the upload speed will match other speedtests:

Screenshot from 2024-07-03 11-10-53

Behind the scenes, the non-flatpak version causes these tracebacks to occur during the upload speed test:

Traceback (most recent call last):
  File "/usr/lib64/python3.12/asyncio/events.py", line 88, in _run
    self._context.run(self._callback, *self._args)
TypeError: 'NoneType' object is not callable
Exception in callback None()
handle: <Handle>

(repeated thousands of times)

Then:

Exception ignored in: <coroutine object LibrespeedBackend.get_servers.<locals>.check_server at 0x7efd0fe9e840>

Traceback (most recent call last):
  File "/usr/share/speedtest/speedtest/backends/librespeed.py", line 36, in check_server
    async with session.get(server.pingURL, timeout=aiohttp.ClientTimeout(total=2.0)) as _:
  File "/usr/lib64/python3.12/site-packages/aiohttp/client.py", line 1197, in __aenter__
    self._resp = await self._coro
                 ^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.12/site-packages/aiohttp/client.py", line 581, in _request
    conn = await self._connector.connect(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.12/site-packages/aiohttp/connector.py", line 544, in connect
    proto = await self._create_connection(req, traces, timeout)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.12/site-packages/aiohttp/connector.py", line 944, in _create_connection
    _, proto = await self._create_direct_connection(req, traces, timeout)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.12/site-packages/aiohttp/connector.py", line 1226, in _create_direct_connection
    transp, proto = await self._wrap_create_connection(
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.12/site-packages/aiohttp/connector.py", line 1025, in _wrap_create_connection
    return await self._loop.create_connection(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.12/asyncio/base_events.py", line 1149, in create_connection
    transport, protocol = await self._create_connection_transport(
                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.12/asyncio/base_events.py", line 1184, in _create_connection_transport
    transport.close()
  File "/usr/lib64/python3.12/asyncio/sslproto.py", line 116, in close
    self._ssl_protocol._start_shutdown()
  File "/usr/lib64/python3.12/asyncio/sslproto.py", line 621, in _start_shutdown
    self._abort(None)
  File "/usr/lib64/python3.12/asyncio/sslproto.py", line 671, in _abort
    self._transport._force_close(exc)
  File "/usr/lib64/python3.12/asyncio/selector_events.py", line 906, in _force_close
    self._loop.call_soon(self._call_connection_lost, exc)
  File "/usr/lib64/python3.12/asyncio/base_events.py", line 795, in call_soon
    self._check_closed()
  File "/usr/lib64/python3.12/asyncio/base_events.py", line 541, in _check_closed
    raise RuntimeError('Event loop is closed')
RuntimeError: Event loop is closed

Task was destroyed but it is pending!
task: <Task pending name='Task-56' coro=<TCPConnector._resolve_host_with_throttle() running at /usr/lib64/python3.12/site-packages/aiohttp/connector.py:917> wait_for=<Future pending cb=[_chain_future.<locals>._call_check_cancel() at /usr/lib64/python3.12/asyncio/futures.py:387, Task.task_wakeup()]> cb=[shield.<locals>._inner_done_callback() at /usr/lib64/python3.12/asyncio/tasks.py:905]>
Task was destroyed but it is pending!
task: <Task pending name='Task-62' coro=<TCPConnector._resolve_host_with_throttle() running at /usr/lib64/python3.12/site-packages/aiohttp/connector.py:917> wait_for=<Future pending cb=[_chain_future.<locals>._call_check_cancel() at /usr/lib64/python3.12/asyncio/futures.py:387, Task.task_wakeup()]> cb=[shield.<locals>._inner_done_callback() at /usr/lib64/python3.12/asyncio/tasks.py:905]>
Task was destroyed but it is pending!
task: <Task pending name='Task-64' coro=<TCPConnector._resolve_host_with_throttle() running at /usr/lib64/python3.12/site-packages/aiohttp/connector.py:917> wait_for=<Future pending cb=[_chain_future.<locals>._call_check_cancel() at /usr/lib64/python3.12/asyncio/futures.py:387, Task.task_wakeup()]> cb=[shield.<locals>._inner_done_callback() at /usr/lib64/python3.12/asyncio/tasks.py:905]>
Exception in callback None()
handle: <Handle>
Traceback (most recent call last):
  File "/usr/lib64/python3.12/asyncio/events.py", line 88, in _run
    self._context.run(self._callback, *self._args)
TypeError: 'NoneType' object is not callable

Maybe the dependencies are packaged differently, or maybe you depend on some newer (or older!) Python library features that have not been reflected in the dependencies metadata?

Version numbers from the Fedora 39 package and its dependencies are:

speedtest                    noarch     1.3.0-1.fc39        @updates      94 k

llhttp                       x86_64     9.2.1-1.fc39        @updates      73 k
python3-aiodns               noarch     3.0.0-8.fc39        @fedora       31 k
python3-aiohttp              x86_64     3.9.5-1.fc39        @updates     3.0 M
python3-aiohttp+speedups     x86_64     3.9.5-1.fc39        @updates     8.0 k
python3-aiosignal            noarch     1.3.1-9.fc39        @fedora       18 k
python3-attrs                noarch     23.1.0-4.fc39       @fedora      379 k
python3-brotli               x86_64     1.1.0-1.fc39        @fedora      820 k
python3-frozenlist           x86_64     1.4.0-2.fc39        @fedora      131 k
python3-multidict            x86_64     6.0.4-3.fc39        @fedora      166 k
python3-pycares              x86_64     4.3.0-4.fc39        @fedora      238 k
python3-yarl                 x86_64     1.9.2-3.fc39        @fedora      306 k
Ketok4321 commented 6 days ago

It happens on newer versions of aiohttp (iirc), but i haven't figured out why yet

nekohayo commented 6 days ago

Could it be related to one of these old issues? Otherwise I suppose your best bet is to ask in their discussions area if they might know of something that recently changed regarding this, I guess 🤔