-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #6 from upupnoah/main
feat(network): support network for simple redis
- Loading branch information
Showing
8 changed files
with
609 additions
and
12 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains 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
This file contains 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
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,11 @@ | ||
mod backend; | ||
mod cmd; | ||
|
||
mod resp; | ||
|
||
pub mod cmd; | ||
pub mod network; | ||
|
||
pub use backend::*; | ||
pub use cmd::*; | ||
// pub use cmd::*; | ||
// pub use network::*; | ||
pub use resp::*; |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,27 @@ | ||
fn main() { | ||
println!("Hello, world!"); | ||
use anyhow::Result; | ||
use simple_redis::{network, Backend}; | ||
use tokio::net::TcpListener; | ||
use tracing::info; | ||
|
||
#[tokio::main] | ||
async fn main() -> Result<()> { | ||
tracing_subscriber::fmt::init(); | ||
|
||
let addr = "0.0.0.0:6389"; | ||
let listener = TcpListener::bind(addr).await?; | ||
info!("Simple-Redis-Server is listening on {}", addr); | ||
|
||
let backend = Backend::new(); | ||
loop { | ||
let (stream, remote_addr) = listener.accept().await?; | ||
info!("Accepted connection from {}", remote_addr); | ||
let cloned_backend = backend.clone(); | ||
tokio::spawn(async move { | ||
// handling of stream | ||
match network::stream_handler(stream, cloned_backend).await { | ||
Ok(_) => info!("Connection from {} closed", remote_addr), | ||
Err(e) => info!("Connection from {} closed with error: {}", remote_addr, e), | ||
} | ||
}); | ||
} | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
use anyhow::Result; | ||
use futures::SinkExt; | ||
use tokio::net::TcpStream; | ||
use tokio_stream::StreamExt; | ||
use tokio_util::codec::{Decoder, Encoder, Framed}; | ||
use tracing::info; | ||
|
||
use crate::{ | ||
cmd::{Command, CommandExecutor}, | ||
Backend, RespDecode, RespEncode, RespError, RespFrame, | ||
}; | ||
|
||
#[derive(Debug)] | ||
struct RedisRequest { | ||
frame: RespFrame, | ||
backend: Backend, | ||
} | ||
|
||
#[derive(Debug)] | ||
struct RedisResponse { | ||
frame: RespFrame, | ||
} | ||
|
||
#[derive(Debug)] | ||
struct RespFrameCodec; | ||
|
||
pub async fn stream_handler(stream: TcpStream, backend: Backend) -> Result<()> { | ||
// how to get a frame from the stream? | ||
let mut framed = Framed::new(stream, RespFrameCodec); | ||
loop { | ||
match framed.next().await { | ||
Some(Ok(frame)) => { | ||
info!("Received frame: {:?}", frame); | ||
let request = RedisRequest { | ||
frame, | ||
backend: backend.clone(), | ||
}; | ||
let response = request_handler(request).await?; | ||
info!("Sending response: {:?}", response.frame); | ||
framed.send(response.frame).await?; | ||
} | ||
Some(Err(e)) => return Err(e), | ||
None => return Ok(()), | ||
} | ||
} | ||
} | ||
|
||
// NOTE: need a backend to process the frame | ||
// async fn request_handler(request: RespFrame) -> Result<RespFrame> { | ||
// todo!() | ||
// } | ||
async fn request_handler(request: RedisRequest) -> Result<RedisResponse> { | ||
let (frame, backend) = (request.frame, request.backend); | ||
let cmd = Command::try_from(frame)?; | ||
info!("Executing command: {:?}", cmd); | ||
let frame = cmd.execute(&backend); | ||
Ok(RedisResponse { frame }) | ||
} | ||
|
||
impl Encoder<RespFrame> for RespFrameCodec { | ||
type Error = anyhow::Error; | ||
|
||
fn encode(&mut self, item: RespFrame, dst: &mut bytes::BytesMut) -> Result<()> { | ||
let encoded = item.encode(); | ||
dst.extend_from_slice(&encoded); | ||
Ok(()) | ||
} | ||
} | ||
|
||
impl Decoder for RespFrameCodec { | ||
type Item = RespFrame; | ||
type Error = anyhow::Error; | ||
|
||
fn decode(&mut self, src: &mut bytes::BytesMut) -> Result<Option<RespFrame>> { | ||
match RespFrame::decode(src) { | ||
Ok(frame) => Ok(Some(frame)), | ||
Err(RespError::NotComplete) => Ok(None), | ||
Err(e) => Err(e.into()), | ||
} | ||
} | ||
} |
This file contains 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