From 9569926e720a374523fee8abe75c267d168f4dae Mon Sep 17 00:00:00 2001 From: Bastian Gruber Date: Thu, 20 Apr 2023 10:58:47 +0200 Subject: [PATCH] Add first attempt for problem-01 --- problem_01/.gitignore | 1 + problem_01/Cargo.toml | 11 ++++-- problem_01/Dockerfile | 12 ++++++ problem_01/fly.toml | 30 +++++++++++++++ problem_01/src/main.rs | 87 +++++++++++++++++++++++++++++++++++++++++- 5 files changed, 136 insertions(+), 5 deletions(-) create mode 100644 problem_01/.gitignore create mode 100644 problem_01/Dockerfile create mode 100644 problem_01/fly.toml diff --git a/problem_01/.gitignore b/problem_01/.gitignore new file mode 100644 index 0000000..b83d222 --- /dev/null +++ b/problem_01/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/problem_01/Cargo.toml b/problem_01/Cargo.toml index 799fe54..ef3ce7b 100644 --- a/problem_01/Cargo.toml +++ b/problem_01/Cargo.toml @@ -1,8 +1,13 @@ [package] -name = "problem_02" +name = "problem_01" version = "0.1.0" edition = "2021" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [dependencies] +bincode = "1.3.3" +env_logger = "0.9.0" +log = "0.4.0" +primes = "0.3.0" +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0.96" +tokio = { version = "1.27.0", features = ["full"] } diff --git a/problem_01/Dockerfile b/problem_01/Dockerfile new file mode 100644 index 0000000..cb1abe3 --- /dev/null +++ b/problem_01/Dockerfile @@ -0,0 +1,12 @@ +FROM rust:latest as builder +RUN apt-get update && apt-get -y install ca-certificates cmake musl-tools libssl-dev && rm -rf /var/lib/apt/lists/* +COPY . . +RUN rustup default stable && rustup update +RUN rustup target add x86_64-unknown-linux-musl +ENV PKG_CONFIG_ALLOW_CROSS=1 +ENV RUST_LOG=info +RUN cargo build --target x86_64-unknown-linux-musl --release +FROM scratch +COPY --from=builder /target/x86_64-unknown-linux-musl/release/problem_01 . +EXPOSE 8080 +CMD ["/problem_01"] diff --git a/problem_01/fly.toml b/problem_01/fly.toml new file mode 100644 index 0000000..b76808d --- /dev/null +++ b/problem_01/fly.toml @@ -0,0 +1,30 @@ +# fly.toml app configuration file generated for hidden-thunder-1268 on 2023-04-19T21:18:46+02:00 +# +# See https://fly.io/docs/reference/configuration/ for information about how to use this file. +# + +app = "hidden-thunder-1268" +primary_region = "ams" + +kill_signal = "SIGINT" +kill_timeout = 5 +processes = [] + +[experimental] + auto_rollback = true + +[env] + ECHO_PORT = "8080" + +[[services]] + protocol = "tcp" + internal_port = 8080 + + [[services.ports]] + port = 8080 + + [[services.tcp_checks]] + grace_period = "5s" + interval = "15s" + restart_limit = 2 + timeout = "2s" diff --git a/problem_01/src/main.rs b/problem_01/src/main.rs index e7a11a9..0d83556 100644 --- a/problem_01/src/main.rs +++ b/problem_01/src/main.rs @@ -1,3 +1,86 @@ -fn main() { - println!("Hello, world!"); +use primes::is_prime; +use serde::{Deserialize, Serialize}; +use tokio::io::AsyncBufReadExt; +use tokio::io::AsyncWriteExt; +use tokio::io::BufReader; +use tokio::net::{TcpListener, TcpStream}; + +const IS_PRIME: &str = "isPrime"; +const MAL_FORMAT: &str = "}mal"; + +#[derive(Debug, Deserialize, Serialize)] +struct Request { + method: String, + number: u64, +} + +#[derive(Debug, Deserialize, Serialize)] +struct Response { + method: String, + prime: bool, +} + +#[tokio::main] +async fn main() -> Result<(), Box> { + env_logger::init(); + let listener = TcpListener::bind("0.0.0.0:8080").await?; + log::info!("Start TCP server"); + + loop { + let (socket, _) = listener.accept().await?; + + tokio::spawn(async move { + log::info!("Handle incoming request"); + let _ = handle_request(socket).await; + }); + } +} + +async fn handle_request(mut socket: TcpStream) { + let (read, mut write) = socket.split(); + + let mut buf: Vec = Vec::new(); + let mut reader = BufReader::new(read); + let bytes = reader.read_until(b'\n', &mut buf).await; + + if let Ok(0) = bytes { + return; + } + + if let Ok(1) = bytes { + return; + } + + match serde_json::from_slice::(&buf) { + Ok(m) => { + log::error!("Message received: {:?}", m); + log::error!("Right method set? {}", m.method == IS_PRIME.to_owned()); + log::error!("Is {} a prime? {}", m.number, is_prime(m.number)); + + let res = Response { + method: IS_PRIME.to_owned(), + prime: is_prime(m.number), + }; + + if m.method == IS_PRIME.to_owned() { + let _ = write + .write(&bincode::serialize(&serde_json::to_string(&res).unwrap()).unwrap()) + .await; + let _ = write.write(&[b'\"', b'\n']).await; + let _ = write.flush().await; + } else { + let _ = write.write(&bincode::serialize(&MAL_FORMAT).unwrap()).await; + let _ = write.write(&[b'\"', b'\n']).await; + let _ = write.flush().await; + } + } + Err(e) => { + log::error!("Error parsing the message: {}", e); + log::error!("Message: {}", String::from_utf8_lossy(&buf)); + + let _ = write.write(&bincode::serialize(&MAL_FORMAT).unwrap()).await; + let _ = write.write(&[b'\"', b'\n']).await; + let _ = write.flush().await; + } + } }