Store values

We will now implement the process function to handle incoming commands. We will use a HashMap to store values. SET commands will insert into the HashMap and GET values will load them. Additionally, we will use a loop to accept more than one command per connection.

  1. use tokio::net::TcpStream;
  2. use mini_redis::{Connection, Frame};
  3. async fn process(socket: TcpStream) {
  4. use mini_redis::Command::{self, Get, Set};
  5. use std::collections::HashMap;
  6. // A hashmap is used to store data
  7. let mut db = HashMap::new();
  8. // Connection, provided by `mini-redis`, handles parsing frames from
  9. // the socket
  10. let mut connection = Connection::new(socket);
  11. // Use `read_frame` to receive a command from the connection.
  12. while let Some(frame) = connection.read_frame().await.unwrap() {
  13. let response = match Command::from_frame(frame).unwrap() {
  14. Set(cmd) => {
  15. // The value is stored as `Vec<u8>`
  16. db.insert(cmd.key().to_string(), cmd.value().to_vec());
  17. Frame::Simple("OK".to_string())
  18. }
  19. Get(cmd) => {
  20. if let Some(value) = db.get(cmd.key()) {
  21. // `Frame::Bulk` expects data to be of type `Bytes`. This
  22. // type will be covered later in the tutorial. For now,
  23. // `&Vec<u8>` is converted to `Bytes` using `into()`.
  24. Frame::Bulk(value.clone().into())
  25. } else {
  26. Frame::Null
  27. }
  28. }
  29. cmd => panic!("unimplemented {:?}", cmd),
  30. };
  31. // Write the response to the client
  32. connection.write_frame(&response).await.unwrap();
  33. }
  34. }

Now, start the server:

  1. $ cargo run

and in a separate terminal window, run the hello-redis example:

  1. $ cargo run --example hello-redis

Now, the output will be:

  1. got value from the server; success=Some(b"world")

We can now get and set values, but there is a problem: The values are not shared between connections. If another socket connects and tries to GET the hello key, it will not find anything.

You can find the full code here.

In the next section, we will implement persisting data for all sockets.