diff options
| author | omagdy <omar.professional8777@gmail.com> | 2025-07-23 04:06:13 +0300 |
|---|---|---|
| committer | omagdy <omar.professional8777@gmail.com> | 2025-07-23 04:06:13 +0300 |
| commit | 1f2f3a241c59f467df5bf16fbde872f5083a174f (patch) | |
| tree | 37af0cc34a97e3efd350b1ee1b872e621e25dca9 /src/main.rs | |
| parent | 8717ae6ab2335cf1a5d34283f272ad728da88667 (diff) | |
| download | redis-rust-1f2f3a241c59f467df5bf16fbde872f5083a174f.tar.xz redis-rust-1f2f3a241c59f467df5bf16fbde872f5083a174f.zip | |
feat: Added syncing with empty RDB file
Diffstat (limited to 'src/main.rs')
| -rw-r--r-- | src/main.rs | 48 |
1 files changed, 44 insertions, 4 deletions
diff --git a/src/main.rs b/src/main.rs index 3186b6c..78b9c24 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,6 +3,7 @@ use core::time; use std::{ collections::HashMap, env, + fmt::format, io::{Read, Write}, net::{TcpListener, TcpStream}, sync::{Arc, Mutex}, @@ -12,6 +13,7 @@ use std::{ use codecrafters_redis::{ rdb::{KeyExpiry, ParseError, RDBFile, RedisValue}, + resp_bytes, shared_cache::*, }; use codecrafters_redis::{resp_commands::RedisCommands, Config}; @@ -38,6 +40,23 @@ fn spawn_cleanup_thread(cache: SharedCache) { }); } +use base64::{engine::general_purpose, Engine as _}; + +fn write_rdb_to_stream<W: Write>(writer: &mut W) -> Result<(), Box<dyn std::error::Error>> { + let hardcoded_rdb = "UkVESVMwMDEx+glyZWRpcy12ZXIFNy4yLjD6CnJlZGlzLWJpdHPAQPoFY3RpbWXCbQi8ZfoIdXNlZC1tZW3CsMQQAPoIYW9mLWJhc2XAAP/wbjv+wP9aog=="; + + let bytes = general_purpose::STANDARD.decode(hardcoded_rdb)?; + + let mut response = format!("${}\r\n", bytes.len()).into_bytes(); + response.extend_from_slice(&bytes); + + // Write the binary RDB data + writer.write_all(&response)?; + + Ok(()) +} + +// TODO: This should return a Result to handle the plethora of different errors fn handle_client(mut stream: TcpStream, cache: SharedCache, config: SharedConfig) { let mut buffer = [0; 512]; @@ -48,11 +67,32 @@ fn handle_client(mut stream: TcpStream, cache: SharedCache, config: SharedConfig Err(_) => return, // error occurred }; - let parsed_resp = parse(&buffer).unwrap(); - let response = RedisCommands::from(parsed_resp.0).execute(cache.clone(), config.clone()); + let request = parse(&buffer).unwrap(); + let response = + RedisCommands::from(request.0.clone()).execute(cache.clone(), config.clone()); + + let mut request_command = "".to_string(); - // write respose back to the client - stream.write(&response).unwrap(); + // FIXME: Find a solution for this mess!! + match &request.0 { + RespType::Array(arr) => { + if let RespType::BulkString(s) = arr[0].clone() { + request_command = String::from_utf8(s).unwrap(); + } + } + _ => {} + } + + // if this true immediately write and send back rdb file after response + // HACK: This just feels wrong I feel this shouldn't be handled here and should be handled + // in the exexute command + if request_command.starts_with("PSYNC") { + stream.write(&response).unwrap(); + let _ = write_rdb_to_stream(&mut stream); + } else { + // write respose back to the client + stream.write(&response).unwrap(); + } } } |
