【rust】tauri+tokio_cron_scheduler+reqwest:解决 "Cannot start a runtime from within a runtime"? 错误
问题背景
需要在tauri框架中引入tokio_cron_scheduler来处理定时任务,并在定时任务中发起http请求,但是在编码后总是由于tokio runtime 嵌套导致报错:"Cannot start a runtime from within a runtime",在查找资料后初步解决了。
参考:
Why does Tokio return the error "Cannot drop a runtime in a context where blocking is not allowed"?
How can I create a Tokio runtime inside another Tokio runtime without getting the error "Cannot start a runtime from within a runtime"?
代码:
use tauri::async_runtime::block_on; use tokio::runtime::Handle; use tokio_cron_scheduler::{JobScheduler, Job}; use reqwest::Client; fn main() { let sched = block_on(initialize_cron_scheduler()); // block_on(init_tokio_cron(sched.clone())); tauri::Builder::default() .manage(sched) .run(tauri::generate_context!()) .expect("error while running tauri application"); } /// /// 使用第三方定时器库 /// 解决多个tokio线程嵌套的问题 /// https://stackoverflow.com/questions/65426683/why-does-tokio-return-the-error-cannot-drop-a-runtime-in-a-context-where-blocki /// https://stackoverflow.com/questions/62536566/how-can-i-create-a-tokio-runtime-inside-another-tokio-runtime-without-getting-th /// pub async fn initialize_cron_scheduler() -> JobScheduler { let cron_handler = JobScheduler::new().await.expect("Failed to initialize tokio cron handler"); cron_handler.start().await.expect("Failed to start tokio cron handler"); // 添加一个请求synching进行扫描的计时器 let heart_job = Job::new("0/8 * * * * *", move |_uuid, _l| { let handle = Handle::current(); tokio::task::spawn_blocking(|| { trigger_synching(handle); }); }).unwrap(); let job_id = cron_handler.add(heart_job).await.unwrap(); cron_handler.clone() } // 主动触发synching程序扫描文件夹变更同步代码变更 fn trigger_synching(handle: Handle) { block_on(async { handle .spawn(async { let client = Client::builder() .danger_accept_invalid_certs(true) .build().unwrap(); let res = client .post("http://127.0.0.1:8384/rest/db/scan?folder=zjfpn-yxrrm") .header("X-API-Key", "xxxxxxxxxxxxxxxxxxxxx") .send() .await; match res { Ok(response) => { println!("主动触发synching扫描文件: {}", response.status()); } Err(err) => { println!("request error: {:?}", err); } } }) .await .expect("Task spawned in Tokio executor panicked") }) }