smbus2 icon indicating copy to clipboard operation
smbus2 copied to clipboard

asyncio support in smbus2

Open jabdoa2 opened this issue 8 years ago • 10 comments

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?

jabdoa2 avatar Mar 01 '18 21:03 jabdoa2

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.

kplindegaard avatar Apr 01 '18 08:04 kplindegaard

https://github.com/jabdoa2/smbus2_asyncio

jabdoa2 avatar Apr 04 '18 21:04 jabdoa2

This async solution should go into the main library!

miili avatar Apr 18 '18 22:04 miili

What are the drawbacks of the Asyncio version? @jabdoa2

AlexisTM avatar May 29 '18 14:05 AlexisTM

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.

kplindegaard avatar May 30 '18 07:05 kplindegaard

I am a user of Python 2.7; And indeed, to keep "'drop-in" replacement of smbus, that support should not be dropped.

AlexisTM avatar May 30 '18 07:05 AlexisTM

@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.

jabdoa2 avatar May 31 '18 06:05 jabdoa2

@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 avatar May 31 '18 06:05 jabdoa2

@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.__init__py

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?

kplindegaard avatar Jun 02 '18 10:06 kplindegaard

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/

uSpike avatar Mar 11 '21 21:03 uSpike