redis_imitate/network/
server.rs

1//! # Server Module
2//! 
3//! Implements the main Redis-like server functionality, handling network listening,
4//! connection management, and thread pool coordination for concurrent client handling.
5use crate::config::config::Config;
6use crate::network::connection::Connection;
7use crate::commands::executor::CommandExecutor;
8use crate::storage::memory::MemoryStorage;
9
10use std::net::{TcpListener, TcpStream};
11use std::io;
12use threadpool::ThreadPool;
13use std::sync::{Arc, Mutex};
14
15pub struct Server {
16    pub config: Arc<Config>,
17    thread_pool: ThreadPool,
18    storage: Arc<Mutex<MemoryStorage>>,
19}
20
21/// Core server structure managing all server components
22/// 
23/// Coordinates:
24/// - Network listening and connection acceptance
25/// - Thread pool for handling concurrent clients
26/// - Shared memory storage
27/// - Server configuration
28impl Server {
29
30   /// Creates a new server instance with the given configuration
31    pub fn new(config: Config) -> Self {
32        let config = Arc::new(config);
33        let thread_pool = ThreadPool::new(config.max_connections);
34        let storage = Arc::new(Mutex::new(MemoryStorage::new()));
35        Server { config, thread_pool, storage }
36    }
37
38   /// Starts the server and begins accepting client connections
39   /// # Server Lifecycle
40   /// 1. Binds to configured host:port
41   /// 2. Accepts incoming connections
42   /// 3. Spawns worker thread for each client
43   /// 4. Manages shared storage across all connections
44    pub fn run(&self) -> io::Result<()> {
45        let address = format!("{}:{}", self.config.host, self.config.port);
46        let listener = TcpListener::bind(&address)?;
47        println!("Server is running on {}", address);
48        
49        for stream in listener.incoming() {
50            match stream {
51                Ok(stream) => {
52                    let storage = Arc::clone(&self.storage);
53                    self.thread_pool.execute(move || {
54                        let executor = Arc::new(CommandExecutor::new(storage));
55                        if let Err(e) = handle_client(stream,  executor) {
56                            eprintln!("Error handling client: {}", e);
57                        }
58                    });
59                }
60                Err(e) => eprintln!("Connection failed: {}", e),
61            }
62        }
63
64        Ok(())
65    }
66}
67
68/// Handles an individual client connection
69fn handle_client(stream: TcpStream, executor: Arc<CommandExecutor>) -> io::Result<()> {
70    let mut connection = Connection::new(stream,  executor);
71    connection.process()
72}