Device gone forever after Ctrl-C or kill
See original GitHub issue- bleak version: 0.8.0
- Python version: 3.7.3
- Operating System: Linux-4.19.0-10-amd64-x86_64-with-debian-10.5
- BlueZ version (
bluetoothctl -v
) in case of Linux: 5.50
Description
If a bleak process with a active connection is terminated with Ctrl-C or kill SIGINT, the BLE device disappears forever. I am unable to reconnect and device do not show up in scan/discovery.
sudo systemctl restart bluetooth
resolves the problem, so it is likely a issue with a “zombie connection” or something in bluez/dbus.
What I Did
This reproduces the problem:
import asyncio
from bleak import BleakClient
import sys
import os
async def main():
address = sys.argv[1]
pid = os.getpid()
async with BleakClient(address) as client:
while 1:
print("press ctrl-C or enter `kill -2 {}` in another shell!".format(str(pid)))
await asyncio.sleep(1)
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
Traceback when pressing ctrl-C:
Traceback (most recent call last):
File "connect_and_exit.py", line 72, in <module>
loop.run_until_complete(main())
File "/usr/lib/python3.7/asyncio/base_events.py", line 571, in run_until_complete
self.run_forever()
File "/usr/lib/python3.7/asyncio/base_events.py", line 539, in run_forever
self._run_once()
File "/usr/lib/python3.7/asyncio/base_events.py", line 1739, in _run_once
event_list = self._selector.select(timeout)
File "/usr/lib/python3.7/selectors.py", line 468, in select
fd_event_list = self._selector.poll(timeout, max_ev)
The following examples works as expected (i.e. BLE device show up in scan). It might seem they should have the same behavior, but apparently not.
async def test_Exception(address):
async with BleakClient(address) as client:
await asyncio.sleep(0.5)
raise Exception
async def test_KeyboardInterrupt(address):
async with BleakClient(address) as client:
await asyncio.sleep(0.5)
raise KeyboardInterrupt
async def test_SIGINT(address):
pid = os.getpid()
async with BleakClient(address) as client:
await asyncio.sleep(0.5)
os.kill(pid, signal.SIGINT)
Traceback when raising KeyboardInterrupt. Note that it differs from the one above!
Traceback (most recent call last):
File "connect_and_exit.py", line 66, in <module>
loop.run_until_complete(main())
File "/usr/lib/python3.7/asyncio/base_events.py", line 571, in run_until_complete
self.run_forever()
File "/usr/lib/python3.7/asyncio/base_events.py", line 539, in run_forever
self._run_once()
File "/usr/lib/python3.7/asyncio/base_events.py", line 1775, in _run_once
handle._run()
File "/usr/lib/python3.7/asyncio/events.py", line 88, in _run
self._context.run(self._callback, *self._args)
File "connect_and_exit.py", line 50, in main
await test_KeyboardInterrupt(address)
File "connect_and_exit.py", line 17, in test_KeyboardInterrupt
raise KeyboardInterrupt
KeyboardInterrupt
I believe this problem was recently introduced as I have not seen it earlier (might have missed it).
Can anyone reproduce it on another system? Ideas?
Issue Analytics
- State:
- Created 3 years ago
- Comments:18 (6 by maintainers)
Top GitHub Comments
Yes, or turn it into a helper method.
We still support Python 3.6, so we would have to do something like this.