Я хочу иметь возможность сделать что-то подобное с Python:
import web_server # Rust based web-server
def callback():
return "Hello world!"
web_server.run(callback)
Где web_server.run
запустит однопоточный веб-сервер Rust и ответит значением, полученным от Python обратный вызов.
Я настраиваю модуль и работаю так:
#[pyfunction]
fn run(py: Python<'static>, callback: PyObject) -> PyResult<()> {
main(py, callback);
Ok(())
}
/// This module is a python module implemented in Rust.
#[pymodule]
fn web_server(_py: Python, m: &PyModule) -> PyResult<()> {
m.add_wrapped(wrap_pyfunction!(run))?;
Ok(())
}
Проблема в том, что я не контролирую время жизни обратного вызова, поэтому, когда я пытаюсь сделать сервис, использующий что-то вроде Hyper:
fn main(py: Python<'static>, callback: PyObject) {
let borrowed_callback = &callback;
// Configure a runtime that runs everything on the current thread
let mut rt = tokio::runtime::Builder::new()
.enable_all()
.basic_scheduler()
.build()
.expect("build runtime")
let local = tokio::task::LocalSet::new();
local.block_on(&mut rt, async {
let make_service = make_service_fn(move |_| {
async move {
Ok::<_, Error>(service_fn(move |_| {
let value: String = borrowed_callback
.call(py, (), None)
.unwrap()
.extract(py)
.unwrap();
async move { Ok::<_, Error>(Response::new(Body::from(value))) }
}))
}
});
let server = Server::bind(&addr).executor(LocalExec).serve(make_service);
...
}
}
Я получаю следующее:
pyo3::object::PyObject
`callback` does not live long enough
borrowed value does not live long enoughrustc(E0597)
lib.rs(13, 29): borrowed value does not live long enough
lib.rs(33, 13): returning this value requires that `callback` is borrowed for `'static`
lib.rs(53, 1): `callback` dropped here while still borrowed
Я довольно новичок в Rust, поэтому не уверен, что что-то упустил просто здесь, или если это просто не реально сейчас. Поскольку я поддерживаю работу веб-сервера в течение всего срока службы программы, похоже, что callback
никогда не следует очищать с помощью Python G C, но я не вижу пути к express, чтобы время жизни объекта 'static
в PyO3.