rust代码无法在部分机器上正常启动?
rust代码无法在部分机器上正常启动部署的机器都是Debian12 x86架构
main.rs
use std::sync::atomic::AtomicBool;
use std::sync::Arc;
mod watchdog;
mod web;
static mut NORMAL_LIST: Vec<String> = Vec::new();
static mut REALITY_LIST: Vec<String> = Vec::new();
#[tokio::main]
pub async fn main() {
// 处理 Ctrl-C 信号
let running = Arc::new(AtomicBool::new(true));
ctrlc::set_handler(move || {
std::process::exit(0);
})
.expect("Error setting Ctrl-C handler");
tokio::spawn(async {
watchdog::start_watch().await;
});
tokio::spawn(async {
web::start_web().await;
});
while running.load(std::sync::atomic::Ordering::Relaxed) {
tokio::time::sleep(tokio::time::Duration::from_secs(1)).await;
}
}
web.rs
use rand::seq::SliceRandom;
use salvo::http::HeaderValue;
use salvo::http::StatusCode;
use salvo::logging::Logger;
use salvo::prelude::*;
use crate::*;
#[handler]
pub async fn avatar(res: &mut Response, req: &Request) {
// 获取 Host
let host = match req.headers().get("Host") {
Some(t) => t.to_str().unwrap(),
_ => {
res.status_code(StatusCode::BAD_REQUEST);
return;
}
};
// 拼接字符串,转成url编码
let host = host.splitn(2, '.').nth(1).unwrap_or("");
let host = format!("resources.{host}");
// 获取 协议类型
let protocol = match req
.headers()
.get("scheme")
.unwrap_or(&HeaderValue::from_static("https"))
.to_str()
.unwrap()
{
"http" => "http",
_ => "https",
};
// 拼接字符串,转成url编码
let host = host.splitn(2, '.').nth(1).unwrap_or("");
let host = format!("resources.{host}");
// 随机从 NORMAL_LIST 中选择一个文件名
unsafe {
let file_name = urlencoding::encode(NORMAL_LIST.choose(&mut rand::thread_rng()).unwrap());
res.render(Redirect::found(format!(
"{protocol}://{host}/avatar/{file_name}"
)));
}
}
#[handler]
pub async fn random(res: &mut Response, req: &Request) {
// 获取查询参数
let img_type = match req.query::<&str>("type") {
Some("reality") => "reality",
_ => "normal",
};
// 获取 Host
let host = match req.headers().get("Host") {
Some(t) => t.to_str().unwrap(),
_ => {
res.status_code(StatusCode::BAD_REQUEST);
return;
}
};
// 拼接字符串,转成url编码
let host = host.splitn(2, '.').nth(1).unwrap_or("");
let host = format!("resources.{host}");
// 获取 协议类型
let protocol = match req
.headers()
.get("scheme")
.unwrap_or(&HeaderValue::from_static("https"))
.to_str()
.unwrap()
{
"http" => "http",
_ => "https",
};
// 随机从中选择一个文件名
unsafe {
let file_name = match img_type {
"reality" => urlencoding::encode(REALITY_LIST.choose(&mut rand::thread_rng()).unwrap()),
_ => urlencoding::encode(NORMAL_LIST.choose(&mut rand::thread_rng()).unwrap()),
};
res.render(Redirect::found(format!(
"{protocol}://{host}/{img_type}/{file_name}"
)));
}
}
pub async fn start_web() {
tracing_subscriber::fmt().try_init().unwrap();
let router = Router::with_path("yuri")
.push(Router::with_path("random").get(random))
.push(Router::with_path("avatar.jpg").get(avatar));
let service = Service::new(router).hoop(Logger::new());
let acceptor = TcpListener::new("127.0.0.1:8081").bind().await;
Server::new(acceptor).serve(service).await;
}
watchdog.rs
use hotwatch::{Event, Hotwatch};
use std::fs;
use std::thread::sleep;
use std::time::Duration;
use crate::*;
pub async fn start_watch() {
// 获取目录下所有文件名
for path in fs::read_dir("../data/output/normal").unwrap() {
unsafe {
NORMAL_LIST.push(path.unwrap().file_name().to_str().unwrap().to_string());
}
}
for path in fs::read_dir("../data/output/reality").unwrap() {
unsafe {
REALITY_LIST.push(path.unwrap().file_name().to_str().unwrap().to_string());
}
}
let mut hotwatch = Hotwatch::new().expect("hotwatch failed to initialize!");
hotwatch
.watch("../data/output/normal", |event: Event| match event.kind {
_ => {
// 清空 NORMAL_LIST
unsafe {
NORMAL_LIST.clear();
}
// 获取目录下所有文件名
for path in fs::read_dir("../data/output/normal").unwrap() {
unsafe {
NORMAL_LIST.push(path.unwrap().file_name().to_str().unwrap().to_string());
}
}
}
})
.expect("failed to watch file!");
hotwatch
.watch("../data/output/reality", |event: Event| match event.kind {
_ => {
// 清空 NORMAL_LIST
unsafe {
REALITY_LIST.clear();
}
// 获取目录下所有文件名
for path in fs::read_dir("../data/output/reality").unwrap() {
unsafe {
REALITY_LIST.push(path.unwrap().file_name().to_str().unwrap().to_string());
}
}
}
})
.expect("failed to watch file!");
loop {
sleep(Duration::from_secs(1));
}
}
部分成功启动机器截图,请忽略找不到路径的报错
启动失败机器截图
尝试1更改x86_64-unknown-linux-gnu为x86_64-unknown-linux-musl 无效
尝试2在watchdog.rs中添加输出代码可以正常输出,在web.rs中进行同样操作没有输出
求大佬解答
回复
1个回答
test
2024-06-19
原因为出现问题的机器只有单线程,代码中有两处使用到了tokio::spawn需要两个线程执行,所以web服务会等待watchdog结束才执行
回复
适合作为回答的
- 经过验证的有效解决办法
- 自己的经验指引,对解决问题有帮助
- 遵循 Markdown 语法排版,代码语义正确
不该作为回答的
- 询问内容细节或回复楼层
- 与题目无关的内容
- “赞”“顶”“同问”“看手册”“解决了没”等毫无意义的内容