Я создаю библиотеку Rust, которая предоставляет следующий простой поток клиентскому приложению C ++:
- Клиентское приложение (CA) вызывает API для создания FooClient, который, среди прочего, создает tokio :: Runtime.
- CA вызывает FooClient.lookup ("{ ссылка }", обратный вызов), где обратный вызов является указателем на функцию.
- FooClient принимает URI и копирует это в структуру контекста. Структура контекста, помимо прочего, имеет ссылку на tokio :: Runtime FooClient. Этот контекст передается через несколько функций бизнес-логики c. Контекст имеет явное время жизни
'a
, поэтому оно короче, чем 'static
. - Когда тяжелая обработка завершена, Rust вызывает заданный ему обратный вызов (он был переведен в FnOnce и отлично работает )
Во время бизнес-логии c Шага 3 часто необходимо сделать веб-запрос, который я хотел бы спланировать асинхронно, используя &tokio::Runtime
, хранящийся в контексте.
Вот упрощенный код, который не компилируется:
fn fork_task(context: &Context, uri: Uri, callback: FnOnce) {
let handle = context.async_scheduler.handle().clone();
let th = thread::spawn(move || {
handle.block_on(async {
call_service(context, uri);
});
});
th.join().unwrap();
callback();
}
Это дает мне следующую ошибку:
error[E0621]: explicit lifetime required in the type of `context`
|
335 | context: &Context,
| -------- help: add explicit lifetime `'static` to the type of `context`: `&Context<'static>`
...
348 | let th = thread::spawn(move || {
| ^^^^^^^^^^^^^ lifetime `'static` required
Фактически это вызывает эту ошибку для каждого параметра, используемого в порождении. , а не только контекст. Однако я не думаю, что 'static
здесь. Я думаю, что во всяком случае, это должно быть 'a
, что связано с явным временем жизни моего контекста.
Есть ли способ обхода проблемы, который я могу сделать? Возможно, с Arc<Mutex<Context>>
, хотя это тоже не похоже, чтобы он делал то, что я хочу, правильно.