matrix-nio icon indicating copy to clipboard operation
matrix-nio copied to clipboard

Use pyo3-asyncio for rewrite

Open ShadowJonathan opened this issue 4 years ago • 0 comments

pyo3-asyncio allows you to write pyo3 python extension modules that integrates rust futures/async runtimes into python's asyncio event loop.

It does this by running a concurrent native thread (pool) for tokio or async-std, and converts/wakes up Futures (rust or python) on both side seamlessly.

An example;

use pyo3::prelude::*;

use std::time::Duration;
use tokio::time::sleep;
use pyo3_asyncio::tokio::into_coroutine;

#[pyfunction]
fn rust_sleep(py: Python) -> PyResult<PyObject> {
    into_coroutine(py, async {
        sleep(Duration::from_secs(1)).await;
        
        Ok(Python::with_gil(|py| py.None()))
    })
}

This wraps the given async closure into a coroutine with py, returns it, allows the asyncio runtime to register it and await for it.

Meanwhile on a seperate tokio worker thread, the async closure is actually executed, it awaits the 1 second sleep, and then returns a python None value to the asyncio event loop as the coroutine's result.


While there would be a lot of boilerplate converting between rust-sdk/ruma's types and python, allowing asyncio and tokio to be used alongside eachother would help with ergonomics and idiomatic code on both ends, a speedy "correct" asyncio matrix library would certainly be appreciated.

ShadowJonathan avatar Jul 13 '21 20:07 ShadowJonathan