-
Notifications
You must be signed in to change notification settings - Fork 301
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
DBus backend high CPU usage and it grows over time #500
Comments
Can you share the full program? Does the high CPU usage still happen when there are no devices to connect to? (This could narrow it down to the scanner code vs. the client code.) |
Yes, sure https://github.com/devbis/ble2mqtt/
That's a good idea, I'll run my code for several days with passive devices only to check the scanner code and post the results later. |
Ran my code for a while in scanning-only mode. I'll try to simplify the code to make a minimal program that just scans devices without complex handling to reduce the impact of my code. |
I checked on the minimal example:
import asyncio as aio
from bleak.backends.device import BLEDevice
from bleak import BleakScanner
def device_detection_callback(device: BLEDevice, advertisement_data):
print(device, advertisement_data)
async def start():
while True:
async with BleakScanner(scanning_mode='passive') as scanner:
scanner.register_detection_callback(
device_detection_callback,
)
await aio.sleep(3)
devices = await scanner.get_discovered_devices()
print('New devices: ', devices)
await aio.sleep(1)
def main():
loop = aio.get_event_loop()
try:
loop.run_until_complete(start())
finally:
loop.close()
if __name__ == '__main__':
main() After working for 12 hours it consumes 95% CPU while scanning and then drops to minimal. |
What happens if you rewrite the loop like this? async def start():
async with BleakScanner(scanning_mode="passive") as scanner:
scanner.register_detection_callback(
device_detection_callback,
)
while True:
await aio.sleep(3)
await scanner.stop()
print("New devices: ", scanner.discovered_devices)
await aio.sleep(1)
await scanner.start() |
Started the new code. Will post the details in 10 hours or so. |
Did you run I've been running the test program for about 24 hours now on my Linux desktop and it is just now sometimes jumping from 0% to 1% of CPU. Are there any exceptions that are being ignored? Have you run with debug logging enabled? You could also run |
In fact, I'm running the script on Freescale i.MX6ULL CP 528 MHz.It is a single-core ARM7 CPU. I suppose it is not as fast as your Linux desktop. :) Yes, I'm running htop to check the current CPU usage of processes.
I ran Then I restarted the python script and check CPU usage. It didn't change much. Then I ran (I wonder can anyone find any clues in the files) The result file has decreased from 5.8 MB to 700 kb. |
Thanks for all of the logs. I have a new theory about what is going on. BlueZ caches information on each device that it sees where a device is identified by its Bluetooth address. However, many Bluetooth Low Energy devices use random addresses that change frequently. So a huge cache of devices builds up in BlueZ, even if there is only one physical device. Each time we start and stop scanning or connect to a client, we create an new D-Bus connection and call So, I think the solution will be to maintain a single D-Bus bus connection for monitoring D-Bus objects for the lifetime of a Bleak program. However, I think it would also be worthwhile raising an issue with BlueZ to see if there is a way for it to not cache devices with random addresses. |
Thanks for looking into it. It is not related to bleak directly, but I home it will help me solve the problem with the cpu. |
https://github.com/igo95862/python-sdbus/ looks interesting as well. |
I suspect I observe the same issue on a raspberry pi 4. Is there a workaround available until a permanent solution is implemented? Bluez 5.50, bleak 0.12.0 Drop in CPU load is after restarting the container / pi.
|
@rbuffat Could you run the same code outside of a Docker container, on the same system, and confirm that the problem exists there as well? |
I periodically restart the |
This fixes a number of bugs by moving the `BleakClient` state management to the new global BlueZ manager object. - Calling "GetManagedObjects" each time we connected caused performance issues. Fixes #500. - Calling "ConnectDevice" didn't work as expected and has been removed/ Fixes #806. - BleakClient didn't handle "InterfacesRemoved" which resulted in an invalid service dictionary in some cases. Fixes #882.
We finally the the changes in place to fix this. Can you please try #902? |
Added ----- * Added new ``assigned_numbers`` module and ``AdvertisementDataType`` enum. * Added new ``bluez`` kwarg to ``BleakScanner`` in BlueZ backend. * Added support for passive scanning in the BlueZ backend. Fixes #606. * Added option to use cached services, characteristics and descriptors in WinRT backend. Fixes #686. * Added ``PendingDeprecationWarning`` to use of ``address_type`` as keyword argument. It will be moved into the ``winrt`` keyword instead according to #623. * Added better error message when adapter is not present in BlueZ backend. Fixes #889. Changed ------- * Add ``py.typed`` file so mypy discovers Bleak's type annotations. * UUID descriptions updated to 2022-03-16 assigned numbers document. * Replace use of deprecated ``asyncio.get_event_loop()`` in Android backend. * Adjust default timeout for ``read_gatt_char()`` with CoreBluetooth to 10s. Merged #891. * ``BleakScanner()`` args ``detection_callback`` and ``service_uuids`` are no longer keyword-only. * ``BleakScanner()`` arg ``scanning_mode`` is no longer Windows-only and is no longer keyword-only. * All ``BleakScanner()`` instances in BlueZ backend now use common D-Bus object manager. * Deprecated ``filters`` kwarg in ``BleakScanner`` in BlueZ backend. * BlueZ version is now checked on first connection instead of import to avoid import side effects. Merged #907. Fixed ----- * Documentation fixes. * On empty characteristic description from WinRT, use the lookup table instead of returning empty string. * Fixed detection of first advertisement in BlueZ backend. Merged #903. * Fixed performance issues in BlueZ backend caused by calling "GetManagedObjects" each time a ``BleakScanner`` scans or ``BleakClient`` is connected. Fixes #500. * Fixed not handling "InterfacesRemoved" in ``BleakClient`` in BlueZ backend. Fixes #882. * Fixed leaking D-Bus socket file descriptors in BlueZ backend. Fixes #805.
Added ----- * Added new ``assigned_numbers`` module and ``AdvertisementDataType`` enum. * Added new ``bluez`` kwarg to ``BleakScanner`` in BlueZ backend. * Added support for passive scanning in the BlueZ backend. Fixes #606. * Added option to use cached services, characteristics and descriptors in WinRT backend. Fixes #686. * Added ``PendingDeprecationWarning`` to use of ``address_type`` as keyword argument. It will be moved into the ``winrt`` keyword instead according to #623. * Added better error message when adapter is not present in BlueZ backend. Fixes #889. Changed ------- * Add ``py.typed`` file so mypy discovers Bleak's type annotations. * UUID descriptions updated to 2022-03-16 assigned numbers document. * Replace use of deprecated ``asyncio.get_event_loop()`` in Android backend. * Adjust default timeout for ``read_gatt_char()`` with CoreBluetooth to 10s. Merged #891. * ``BleakScanner()`` args ``detection_callback`` and ``service_uuids`` are no longer keyword-only. * ``BleakScanner()`` arg ``scanning_mode`` is no longer Windows-only and is no longer keyword-only. * All ``BleakScanner()`` instances in BlueZ backend now use common D-Bus object manager. * Deprecated ``filters`` kwarg in ``BleakScanner`` in BlueZ backend. * BlueZ version is now checked on first connection instead of import to avoid import side effects. Merged #907. Fixed ----- * Documentation fixes. * On empty characteristic description from WinRT, use the lookup table instead of returning empty string. * Fixed detection of first advertisement in BlueZ backend. Merged #903. * Fixed performance issues in BlueZ backend caused by calling "GetManagedObjects" each time a ``BleakScanner`` scans or ``BleakClient`` is connected. Fixes #500. * Fixed not handling "InterfacesRemoved" in ``BleakClient`` in BlueZ backend. Fixes #882. * Fixed leaking D-Bus socket file descriptors in BlueZ backend. Fixes #805.
bluetoothctl -v
) in case of Linux: 5.50Description
I'm using bleak to run scanning devices and connect to some other devices.
When I start my application it consumes high CPU percent but it is affordable.
About 30-60% of the 800MHz device.
And my application is responsive at the start so it is affordable.
After working for 10-20 hours CPU usage raising and it could take 95-100% all the time.
The problem It that it leads to timeout exceptions while tasks don't get their CPU time.
What I Did
bluetoothd
to flush caches or so, it didn't helpActually, I'm empty of ideas how I can stop this growing CPU usage. What else can I check to find out the root of the problem?
The text was updated successfully, but these errors were encountered: