Last active
July 20, 2022 10:27
-
-
Save chiro-hiro/a17285a86867e93e71fbf43537319b81 to your computer and use it in GitHub Desktop.
Multithread HTTP server with crossbeam
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Try with | |
// RUST_LOG=debug cargo run | |
// [dependencies] | |
// crossbeam = "0.8.1" | |
// crossbeam-utils = "0.8.10" | |
// crossbeam-channel = "0.5" | |
// log = "0.4.17" | |
// env_logger = "0.9.0" | |
use crossbeam; | |
use crossbeam_utils::atomic::AtomicCell; | |
use log::{debug, info}; | |
use std::fmt::Error; | |
use std::io::{BufRead, BufReader, Write}; | |
use std::net::{Ipv4Addr, SocketAddrV4, TcpListener, TcpStream}; | |
fn handle_connection(mut tcp_stream: TcpStream) { | |
let socket_addr = tcp_stream.peer_addr().unwrap(); | |
let mut reader = BufReader::new(&tcp_stream); | |
let mut buf = String::new(); | |
reader.read_line(&mut buf).unwrap(); | |
let contents = "Hello darkness!"; | |
let response = format!( | |
"{}\r\nContent-Length: {}\r\n\r\n{}", | |
"HTTP/1.1 200 OK", | |
contents.len(), | |
contents | |
); | |
debug!( | |
"Remote address:\n{}\nRequest:\n{}\nResponse:\n{}\n", | |
socket_addr.to_string(), | |
buf, | |
response | |
); | |
tcp_stream.write(response.as_bytes()).unwrap(); | |
tcp_stream.flush().unwrap(); | |
} | |
fn main() -> Result<(), Error> { | |
env_logger::init(); | |
let loopback = "127.0.0.1".parse::<Ipv4Addr>().unwrap(); | |
let socket = SocketAddrV4::new(loopback, 8080); | |
let listener = TcpListener::bind(socket).unwrap(); | |
let port = listener.local_addr().unwrap(); | |
info!("Listening on: {}", port); | |
const THREAD_THRESHOLD: u32 = 10; | |
let thread_count = AtomicCell::new(THREAD_THRESHOLD); | |
thread_count.store(0); | |
crossbeam::scope(|s| loop { | |
if thread_count.load() < 10 { | |
for stream in listener.incoming() { | |
s.spawn(|_| { | |
thread_count.store(thread_count.load() + 1); | |
info!("Activated thread: {}", thread_count.load()); | |
handle_connection(stream.unwrap()); | |
thread_count.store(thread_count.load() - 1); | |
}); | |
} | |
} | |
}) | |
.unwrap(); | |
Ok(()) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment