61 lines
1.4 KiB
Rust
61 lines
1.4 KiB
Rust
|
use std::io::{Read, Write};
|
||
|
use std::net::{TcpListener, TcpStream};
|
||
|
use std::sync::{Arc, RwLock};
|
||
|
|
||
|
use anyhow::{bail, Result};
|
||
|
|
||
|
use crate::bank::Bank;
|
||
|
use crate::commands::Commands;
|
||
|
use crate::protocol;
|
||
|
use crate::threadpool::ThreadPool;
|
||
|
|
||
|
pub fn run(host: &str, threads: usize) -> Result<()> {
|
||
|
let listener = TcpListener::bind(host)?;
|
||
|
let pool = ThreadPool::new(threads);
|
||
|
let cmds = Arc::new(Commands::new());
|
||
|
|
||
|
let bank = Arc::new(RwLock::new(Bank::new()));
|
||
|
|
||
|
for stream in listener.incoming() {
|
||
|
let cmds = cmds.clone();
|
||
|
let bank = bank.clone();
|
||
|
|
||
|
let stream = stream?;
|
||
|
|
||
|
pool.execute(move || {
|
||
|
if let Err(e) = handle_connection(bank, &cmds, stream) {
|
||
|
error!("{}", e);
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
|
||
|
Ok(())
|
||
|
}
|
||
|
|
||
|
fn handle_connection(bank: Arc<RwLock<Bank>>, cmds: &Commands, mut stream: TcpStream) -> Result<()> {
|
||
|
const BUF_SIZE: usize = 64;
|
||
|
|
||
|
let mut data: Vec<u8> = vec![];
|
||
|
let mut buffer = [0; BUF_SIZE];
|
||
|
|
||
|
let mut read = stream.read(&mut buffer)?;
|
||
|
while read > 0 {
|
||
|
data.append(&mut buffer[..read].to_vec());
|
||
|
read = stream.read(&mut buffer)?;
|
||
|
}
|
||
|
|
||
|
if data[..2] != protocol::START {
|
||
|
bail!("got {:?} as first bytes, not my problem", &data[..2]);
|
||
|
}
|
||
|
|
||
|
let cmd: u8 = (data[2] & 0b1111_0000) >> 4;
|
||
|
trace!("got command {}", cmd);
|
||
|
|
||
|
cmds.run(bank, cmd, &data[3..], &stream)?;
|
||
|
|
||
|
stream.flush()?;
|
||
|
|
||
|
Ok(())
|
||
|
}
|
||
|
|