Open jabdoa2 opened 6 years ago
Hello and sorry for late response.
It sounds interesting to have an asyncio implementation, so feel free to fork and implement what you need. Couldn't be happier. However, I am inclined to think that an async version is such a large improvement that it is probably better served as a separate library.
This async solution should go into the main library!
What are the drawbacks of the Asyncio version? @jabdoa2
As far as I know, asyncio came in Python 3.4, and I would like smbus2 should work for 2.7 as well. There are ways to overcome that of course. PS: Seems I should withdraw parts of my previous comment about large (in terms of code size) improvement. Not very familiar with asyncio as you guys understand.
I am a user of Python 2.7; And indeed, to keep "'drop-in" replacement of smbus, that support should not be dropped.
@alexistm The current asyncio implementation will probably use slightly more CPU. However, I2C is usually not used to exchange data at very high data rates so it should be fine. I guess that this could also get optimized if it becomes a problem.
@kplindegaard there are some asyncio backports for 2.7. However, those async functions could exist in addition to the sync functions and would not break backwards compatibility.
@jabdoa2 A very simple merge option is to just import the asyncio class if Python version is 3.4 or higher. For example append this to smbus2.initpy
from platform import python_version_tuple
if python_version_tuple() >= (3, 4):
from .smbus2_asyncio import SMBus2Asyncio
and just copy your smbus2_asyncio.py right into this repo. I think that should suffice and I would be honered to have it in. But would you be comfortable with that?
I'd just like to add that it'd be great if an async implementation could utilize anyio
so that the project could be reused with asyncio
and trio
: https://anyio.readthedocs.io/en/stable/
We use smbus2 in the Mission Pinball Framework (https://github.com/missionpinball/mpf/). However, MPF is an asyncio application and most operations will block for a while. It certainly works because I2C is fast but we would like to keep latency down in the app. I looked into non-blocking mode for the smbus interface and i2c on Linux in general but i looks like that either does not work or nobody uses it. So we can probably not use select (or epoll) via the asyncio loop. Let me know if you thing that this would work.
However, I would like to have an asyncio smbus implementation anyway. Would you be up to merge a change where all ioctls would happen in an executor (a separate thread in asyncio) which synchronizes via two queues? That way the asyncio app would not have to block when performing operations and the library would only require minimal changes. What do you think?