Add tokio

This commit is contained in:
DefectingCat
2023-03-24 15:46:57 +08:00
parent 5658ba230f
commit fe7c0372e3
4 changed files with 158 additions and 28 deletions

137
Cargo.lock generated
View File

@ -44,6 +44,12 @@ version = "3.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535"
[[package]]
name = "bytes"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be"
[[package]]
name = "candy"
version = "0.1.0"
@ -58,6 +64,7 @@ dependencies = [
"serde",
"serde_json",
"thiserror",
"tokio",
]
[[package]]
@ -337,6 +344,16 @@ version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4"
[[package]]
name = "lock_api"
version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df"
dependencies = [
"autocfg",
"scopeguard",
]
[[package]]
name = "log"
version = "0.4.17"
@ -352,6 +369,18 @@ version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
[[package]]
name = "mio"
version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9"
dependencies = [
"libc",
"log",
"wasi 0.11.0+wasi-snapshot-preview1",
"windows-sys",
]
[[package]]
name = "nix"
version = "0.26.2"
@ -405,6 +434,35 @@ version = "6.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee"
[[package]]
name = "parking_lot"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
dependencies = [
"lock_api",
"parking_lot_core",
]
[[package]]
name = "parking_lot_core"
version = "0.9.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521"
dependencies = [
"cfg-if",
"libc",
"redox_syscall",
"smallvec",
"windows-sys",
]
[[package]]
name = "pin-project-lite"
version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116"
[[package]]
name = "proc-macro-error"
version = "1.0.4"
@ -447,6 +505,15 @@ dependencies = [
"proc-macro2",
]
[[package]]
name = "redox_syscall"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
dependencies = [
"bitflags",
]
[[package]]
name = "regex"
version = "1.7.1"
@ -484,6 +551,12 @@ version = "1.0.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041"
[[package]]
name = "scopeguard"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "scratch"
version = "1.0.5"
@ -521,6 +594,31 @@ dependencies = [
"serde",
]
[[package]]
name = "signal-hook-registry"
version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1"
dependencies = [
"libc",
]
[[package]]
name = "smallvec"
version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"
[[package]]
name = "socket2"
version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662"
dependencies = [
"libc",
"winapi",
]
[[package]]
name = "static_assertions"
version = "1.1.0"
@ -580,10 +678,41 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a"
dependencies = [
"libc",
"wasi",
"wasi 0.10.0+wasi-snapshot-preview1",
"winapi",
]
[[package]]
name = "tokio"
version = "1.26.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03201d01c3c27a29c8a5cee5b55a93ddae1ccf6f08f65365c2c918f8c1b76f64"
dependencies = [
"autocfg",
"bytes",
"libc",
"memchr",
"mio",
"num_cpus",
"parking_lot",
"pin-project-lite",
"signal-hook-registry",
"socket2",
"tokio-macros",
"windows-sys",
]
[[package]]
name = "tokio-macros"
version = "1.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "unicode-ident"
version = "1.0.8"
@ -608,6 +737,12 @@ version = "0.10.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "wasm-bindgen"
version = "0.2.84"

View File

@ -16,3 +16,4 @@ num_cpus = "1.15.0"
serde = { version = "1.0.152", features = ["derive"] }
serde_json = "1.0.93"
thiserror = "1.0.39"
tokio = { version = "1.26.0", features = ["full"] }

View File

@ -24,7 +24,7 @@ use crate::frame::HttpFrame;
/// Handle get request.
/// params path: static file folder path in config.
/// params route: request route.
pub fn handle_get(
pub async fn handle_get(
path: &PathBuf,
route: &str,
try_index: bool,
@ -62,7 +62,7 @@ pub fn handle_get(
};
debug!("access path {path:?}");
let contents = match fs::read(&path) {
let contents = match tokio::fs::read(&path).await? {
Ok(content) => content,
Err(err) => {
debug!("{err:?}");
@ -129,7 +129,7 @@ pub fn handle_not_found(path: &PathBuf, mut stream: &TcpStream) {
stream.write_all(response.as_bytes()).unwrap();
}
pub fn handle_connection(mut stream: &TcpStream, config: Arc<Mutex<Config>>) {
pub async fn handle_connection(mut stream: &TcpStream, config: Arc<Mutex<Config>>) {
let mut buf_reader = BufReader::new(&mut stream);
let HttpFrame {
@ -190,7 +190,7 @@ pub fn handle_connection(mut stream: &TcpStream, config: Arc<Mutex<Config>>) {
return handle_error(stream);
}
};
match handle_get(path, route, try_index) {
match handle_get(path, route, try_index).await {
Ok(res) => res,
Err(err) => {
return match err {

View File

@ -1,15 +1,14 @@
use std::net::TcpListener;
use std::process::exit;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Arc, Mutex};
use std::thread;
use anyhow::Result;
use log::{error, info};
use config::Config;
use tokio::net::TcpListener;
use crate::handles::handle_connection;
use crate::thread_pool::ThreadPool;
mod args;
mod config;
@ -20,7 +19,8 @@ mod handles;
mod logger;
mod thread_pool;
fn main() {
#[tokio::main]
async fn main() -> Result<()> {
let running = Arc::new(AtomicBool::new(true));
let r = Arc::clone(&running);
ctrlc::set_handler(move || r.store(false, Ordering::SeqCst)).expect("");
@ -32,8 +32,6 @@ fn main() {
}
info!("Server starting.");
let work_num = config.lock().expect("").works.unwrap();
let thread_pool = Arc::new(Mutex::new(ThreadPool::new(work_num)));
let (addr, port) = {
let host = &config.lock().expect("Can not get config file.").host;
let addr = if let Some(addr) = &host.listen_addr {
@ -48,24 +46,20 @@ fn main() {
};
(addr, port)
};
let listener = TcpListener::bind(format!("{addr}:{port}")).unwrap_or_else(|err| {
error!("Can not listen on {addr}:{port}; {}", err.to_string());
exit(1);
});
let pool = Arc::clone(&thread_pool);
thread::spawn(move || {
for stream in listener.incoming() {
let config = Arc::clone(&config);
let stream = stream.unwrap();
let job = Box::new(move || {
handle_connection(&stream, config);
});
pool.lock().unwrap().execute(job);
}
});
let listener = TcpListener::bind(format!("{addr}:{port}")).await?;
info!("Listen on {addr}:{port}.");
while running.load(Ordering::SeqCst) {}
thread_pool.lock().unwrap().exit();
while running.load(Ordering::SeqCst) {
let (mut stream, _) = listener.accept().await?;
let config = Arc::clone(&confg);
tokio::task::spawn(async move {
handle_connection(&stream, config);
});
}
println!("Exiting...");
Ok(())
}