我兩周前開始學習 rust,并且一直在制作這個應用程式來監視日志檔案,并將大量資訊發送到彈性搜索資料庫。
問題是,經過一定時間后,它會凍結(使用 100% CPU),我不明白為什么。
我已經減少了很多代碼來試圖找出問題,但是根據 clion 除錯器它仍然在這條線上凍結
let _response = reqwest::Client::new()
.post("http://127.0.0.1/test.php")
.header("Content-Type", "application/json")
.body("{\"test\": true}")
.timeout(Duration::from_secs(30))
.send() // <-- Exactly here
.await;
它凍結并且不回傳任何錯誤訊息。
這是背景關系中的代碼:
use std::{env};
use std::io::{stdout, Write};
use std::path::Path;
use std::time::Duration;
use logwatcher::{LogWatcher, LogWatcherAction};
use serde_json::{json, Value};
use serde_json::Value::Null;
use tokio;
#[tokio::main]
async fn main() {
let mut log_watcher = LogWatcher::register("/var/log/test.log").unwrap();
let mut counter = 0;
let BULK_SIZE = 500;
log_watcher.watch(&mut move |line: String| { // This triggers each time a new line is appended to /var/log/test.log
counter = 1;
if counter >= BULK_SIZE {
futures::executor::block_on(async { // This has to be async because log_watcher is not async
let _response = reqwest::Client::new()
.post("http://127.0.0.1/test.php") // <-- This is just for testing, it fails towards the DB too
.header("Content-Type", "application/json")
.body("{\"test\": true}")
.timeout(Duration::from_secs(30))
.send() // <-- Freezes here
.await;
if _response.is_ok(){
println!("Ok");
}
});
counter = 0;
}
LogWatcherAction::None
});
}
日志檔案每分鐘獲取大約 625 行新行。崩潰發生在大約 5500 - 25000 行之后,或者總體上看起來有點隨機。
我懷疑這個問題與LogWatcher、reqwest、block_on或 async 的混合有關。
有誰知道為什么它會隨機凍結?
uj5u.com熱心網友回復:
問題確實是由于混合了asyncwithtokio和block_on,而不是直接 reqwest。
當將 main 更改為非異步并使用 tokio 作為異步呼叫的 block_on 而不是futures::executor::block_on.
fn main() {
let mut log_watcher = LogWatcher::register("/var/log/test.log").unwrap();
let mut counter = 0;
let BULK_SIZE = 500;
log_watcher.watch(&mut move |line: String| {
counter = 1;
if counter >= BULK_SIZE {
tokio::runtime::Builder::new_multi_thread()
.enable_all()
.build()
.unwrap()
.block_on(async {
let _response = reqwest::Client::new()
.post("http://127.0.0.1/test.php")
.header("Content-Type", "application/json")
.body("{\"test\": true}")
.timeout(Duration::from_secs(30))
.send()
.await;
if _response.is_ok(){
println!("Ok");
}
});
counter = 0;
}
LogWatcherAction::None
});
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/510749.html
標籤:http异步锈要求韦斯特
