No project description provided
Project description
uringloop
A Python implementation of a liburing-based proactor event loop for asyncio, designed to follow Python standard library conventions. The implementation is written primarily in pure Python, using CFFI only for wrapping the liburing interface.
- Implements a Proactor pattern similar to Windows' IOCP (reference implementation)
- Follows Python's standard asyncio implementation patterns
⚠️ Note: This is currently experimental and not yet stable
Goals
- Provide a primarily Python (with CFFI, maybe C extention in future) implementation of a liburing-based event loop
- Maintain full compatibility with standard asyncio APIs
- Follow Python standard library implementation patterns
Requirements
-
Linux 5.19+ kernel
-
Python 3.12+
-
liburing development libraries
sudo apt install liburing-dev
Installation
uv add uringloop
Quick Start
Set the event loop policy with asyncio.set_event_loop_policy(IouringProactorEventLoopPolicy()) to use the io_uring-based event loop.
import asyncio
from uringloop import IouringProactorEventLoopPolicy
asyncio.set_event_loop_policy(IouringProactorEventLoopPolicy())
async def handle_client(reader: asyncio.StreamReader, writer: asyncio.StreamWriter):
addr = writer.get_extra_info('peername')
print(f"Connection from {addr}")
while True:
data = await reader.read(1024)
if not data:
break
print(f"Received: {data.decode()}")
writer.write(data)
await writer.drain()
print(f"Connection with {addr} closed")
writer.close()
async def start_server():
server = await asyncio.start_server(
handle_client, '127.0.0.1', 8888)
addr = server.sockets[0].getsockname()
print(f'Serving on {addr}')
async with server:
await server.serve_forever()
async def tcp_client(message: str):
reader, writer = await asyncio.open_connection(
'127.0.0.1', 8888)
print(f'Send: {message!r}')
writer.write(message.encode())
await writer.drain()
data = await reader.read(100)
print(f'Received: {data.decode()!r}')
print('Closing connection')
writer.close()
await writer.wait_closed()
async def main():
# Start the server in the background
server_task = asyncio.create_task(start_server())
# Give the server a moment to start
await asyncio.sleep(1)
# Run the client
await tcp_client('Hello, World!')
# Cancel the server task (otherwise it runs forever)
server_task.cancel()
try:
await server_task
except asyncio.CancelledError:
pass
if __name__ == "__main__":
asyncio.run(main())
the result would looks like
Serving on ('127.0.0.1', 8888)
Send: 'Hello, World!'
Connection from ('0.0.0.0', 0)
Received: Hello, World!
Received: 'Hello, World!'
Closing connection
Connection with ('0.0.0.0', 0) closed
Contributing
Contributions are welcome! Please open issues or pull requests for any bugs or feature requests.
License
This project is licensed under the terms of the MIT license.
TODO
- workflow
- use registered fd and buffer
- add signal handling
- refactor e2e test
- benchmark
- figure out a way to do unit/integration test
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
File details
Details for the file uringloop-0.1.0.tar.gz.
File metadata
- Download URL: uringloop-0.1.0.tar.gz
- Upload date:
- Size: 316.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6d7f089a049d44c15dafb190a9b90a2e18fc6f7a552a64ddf345b6633bbd73ed
|
|
| MD5 |
b01448c38244ae30e41bf4cc777f948d
|
|
| BLAKE2b-256 |
3c98cac0cb3d841c0d6e2ddd79fa7beb5798189550cdf38b8326a3640f1b47fe
|