Skip to content

Ch 04 - Solution for Mac users that want to run the epoll examples using docker #19

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions ch04/a-epoll/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
FROM rust:1-slim-bookworm

WORKDIR /usr/a-epoll

COPY . .

RUN cargo build

CMD ["cargo", "run", "delayserver"]
3 changes: 3 additions & 0 deletions ch04/a-epoll/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ additional comments that's not in the book.

You can run the example by simply writing `cargo run`

If running on a Mac system (which only supports kqueue but not epoll), docker
can be used to run the example by running the epoll_docker.sh script

## Note

There is one downside of having a local server on the same machine to mimic
Expand Down
17 changes: 17 additions & 0 deletions ch04/a-epoll/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
services:
delayserver:
build: ../../delayserver/
ports:
- "8080:8080"
networks:
- delayserver_network

epoll:
build: .
depends_on:
- delayserver
networks:
- delayserver_network

networks:
delayserver_network: {}
3 changes: 3 additions & 0 deletions ch04/a-epoll/epoll_docker.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/bash

docker compose up --build
13 changes: 11 additions & 2 deletions ch04/a-epoll/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use std::{
collections::HashSet,
io::{self, Read, Result, Write},
net::TcpStream,
env
};

use ffi::Event;
Expand Down Expand Up @@ -82,13 +83,21 @@ fn main() -> Result<()> {
let n_events = 5;

let mut streams = vec![];
let addr = "localhost:8080";

let args: Vec<String> = env::args().collect();
let base_url;
if args.len() > 1 {
base_url = args[1].clone();
} else {
base_url = String::from("localhost");
}
let addr = format!("{}:8080", &base_url);

for i in 0..n_events {
let delay = (n_events - i) * 1000;
let url_path = format!("/{delay}/request-{i}");
let request = get_req(&url_path);
let mut stream = std::net::TcpStream::connect(addr)?;
let mut stream = std::net::TcpStream::connect(&addr)?;
stream.set_nonblocking(true)?;

stream.write_all(request.as_bytes())?;
Expand Down
9 changes: 9 additions & 0 deletions ch04/b-epoll-mio/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
FROM rust:1-slim-bookworm

WORKDIR /usr/a-epoll

COPY . .

RUN cargo build

CMD ["cargo", "run", "delayserver"]
5 changes: 4 additions & 1 deletion ch04/b-epoll-mio/README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
# a-epoll-mio
# b-epoll-mio

This create contains the example code for chapter 4, but instead of using
our own queue, we use one created by [mio](https://github.com/tokio-rs/mio). Since we modelled our own code after
mio you only need to make a few very minor changes to get it working which I've
commented and marked out as clearly as I can.

If running on a Mac system (which only supports kqueue but not epoll), docker
can be used to run the example by running the epoll_mio_docker.sh script

You can run the example by simply writing `cargo run`

## Note
Expand Down
17 changes: 17 additions & 0 deletions ch04/b-epoll-mio/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
services:
delayserver:
build: ../../delayserver/
ports:
- "8080:8080"
networks:
- delayserver_network

epoll-mio:
build: .
depends_on:
- delayserver
networks:
- delayserver_network

networks:
delayserver_network: {}
3 changes: 3 additions & 0 deletions ch04/b-epoll-mio/epoll_mio_docker.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/bash

docker compose up --build
15 changes: 12 additions & 3 deletions ch04/b-epoll-mio/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,12 @@
//! I don't consider this a bug with our code but a surprising behavior of the
//! WSL/Windows network stack. Anyway, if you encounter this, the fix is simple:
//!
//! Change `let addr = "localhost:8080";` to `let addr = "127.0.0.1:8080";`.
//! Change `base_url = String::from("localhost");` to `base_url = String::from("127.0.0.1");`.
//!

// FIX #4 (import `HashSet``)
use std::collections::HashSet;
use std::env;
use std::io::{self, Read, Result, Write};

use mio::event::Event;
Expand Down Expand Up @@ -89,13 +90,21 @@ fn main() -> Result<()> {
let n_events = 5;

let mut streams = vec![];
let addr = "localhost:8080";

let args: Vec<String> = env::args().collect();
let base_url;
if args.len() > 1 {
base_url = args[1].clone();
} else {
base_url = String::from("localhost");
}
let addr = format!("{}:8080", &base_url);

for i in 0..n_events {
let delay = (n_events - i) * 1000;
let url_path = format!("/{delay}/request-{i}");
let request = get_req(&url_path);
let std_stream = std::net::TcpStream::connect(addr)?;
let std_stream = std::net::TcpStream::connect(&addr)?;
std_stream.set_nonblocking(true)?;

// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Expand Down
9 changes: 9 additions & 0 deletions delayserver/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
FROM rust:1-slim-bookworm

WORKDIR /usr/delayserver

COPY . .

RUN cargo build

CMD ["cargo", "run", "delayserver"]
10 changes: 10 additions & 0 deletions delayserver/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
services:
delayserver:
build: .
ports:
- 8080
networks:
- network1

networks:
network1: {}
19 changes: 15 additions & 4 deletions delayserver/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
use std::{time::Duration, sync::atomic::{AtomicUsize, Ordering}};
use std::{time::Duration, sync::atomic::{AtomicUsize, Ordering}, env};
use actix_web::{Responder, get, HttpServer, App, web, rt::time::sleep};

const EXPLANATION: &str =
"USAGE:
Delay server works by issuing a http GET request in the format:
http://localhost:8080/[delay in ms]/[UrlEncoded message]

On reception, it immediately reports the following to the console:
If an argument is passed in when delayserver is started, that
argument will be used as the url instead of 'localhost'

On reception, it immieiately reports the following to the console:

{Message #} - {delay in ms}: {message}

The server then delays the response for the requested time and echoes the message back to the caller.
Expand All @@ -27,12 +31,19 @@ async fn delay(path: web::Path<(u64, String)>) -> impl Responder {

#[actix_web::main]
async fn main() -> std::io::Result<()> {
let args: Vec<String> = env::args().collect();
let url;
if args.len() > 1 {
url = args[1].clone();
} else {
url = String::from("localhost");
}
println!("{EXPLANATION}");
HttpServer::new(|| {
App::new()
.service(delay)
})
.bind(("127.0.0.1", 8080))?
.bind((url, 8080))?
.run()
.await
}
}