diff --git a/Cargo.toml b/Cargo.toml index f6b62232..d9217891 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,7 +27,7 @@ members = [ "redis-session", "run-in-thread", "rustls", - "self-shutdown-route", + "shutdown-server", "server-sent-events", "simple-auth-server", "state", diff --git a/async_pg/Cargo.toml b/async_pg/Cargo.toml index 20706a55..5ac11a7c 100644 --- a/async_pg/Cargo.toml +++ b/async_pg/Cargo.toml @@ -3,6 +3,7 @@ name = "async_pg" version = "0.1.0" authors = ["dowwie "] edition = "2018" +workspace = ".." [dependencies] actix-rt = "1.0.0" @@ -12,6 +13,7 @@ deadpool-postgres = "0.5.0" derive_more = "0.99.2" dotenv = "0.15.0" serde = { version = "1.0.104", features = ["derive"] } +tokio = { version = "0.2.11", features = ["signal"] } tokio-pg-mapper = "0.1.4" tokio-pg-mapper-derive = "0.1.4" tokio-postgres = "0.5.1" diff --git a/async_pg/README.md b/async_pg/README.md index 5552fb6e..77ce5e6f 100644 --- a/async_pg/README.md +++ b/async_pg/README.md @@ -43,7 +43,7 @@ ```ini SERVER_ADDR=127.0.0.1:8080 PG.USER=test_user - PG.PASSWD=testing + PG.PASSWORD=testing PG.HOST=127.0.0.1 PG.PORT=5432 PG.DBNAME=testing_db diff --git a/async_pg/src/main.rs b/async_pg/src/main.rs index 09bfb665..80d154aa 100644 --- a/async_pg/src/main.rs +++ b/async_pg/src/main.rs @@ -1,6 +1,6 @@ mod config { - use serde::Deserialize; pub use ::config::ConfigError; + use serde::Deserialize; #[derive(Deserialize)] pub struct Config { pub server_addr: String, @@ -49,6 +49,9 @@ mod errors { fn error_response(&self) -> HttpResponse { match *self { MyError::NotFound => HttpResponse::NotFound().finish(), + MyError::PoolError(ref err) => { + HttpResponse::InternalServerError().body(err.to_string()) + } _ => HttpResponse::InternalServerError().finish(), } } @@ -107,6 +110,7 @@ mod handlers { use actix_web::{web, App, HttpServer}; use dotenv::dotenv; use handlers::add_user; +use tokio::signal::unix::{signal, SignalKind}; use tokio_postgres::NoTls; #[actix_rt::main] @@ -125,5 +129,15 @@ async fn main() -> std::io::Result<()> { .run(); println!("Server running at http://{}/", config.server_addr); + let srv = server.clone(); + let mut stream = signal(SignalKind::interrupt())?; + actix_rt::spawn(async move { + loop { + stream.recv().await; + println!("\nSIGINT Received. Stopping server.\n"); + srv.stop(true).await; + } + }); + server.await } diff --git a/basics/src/main.rs b/basics/src/main.rs index efd57f24..2fee54f5 100644 --- a/basics/src/main.rs +++ b/basics/src/main.rs @@ -92,13 +92,11 @@ async fn main() -> io::Result<()> { _ => HttpResponse::NotFound(), }), ) - .service(web::resource("/error").to(|| { - async { - error::InternalError::new( - io::Error::new(io::ErrorKind::Other, "test"), - StatusCode::INTERNAL_SERVER_ERROR, - ) - } + .service(web::resource("/error").to(|| async { + error::InternalError::new( + io::Error::new(io::ErrorKind::Other, "test"), + StatusCode::INTERNAL_SERVER_ERROR, + ) })) // static files .service(fs::Files::new("/static", "static").show_files_listing()) diff --git a/middleware/src/main.rs b/middleware/src/main.rs index 1598a2a0..c2237beb 100644 --- a/middleware/src/main.rs +++ b/middleware/src/main.rs @@ -30,13 +30,11 @@ async fn main() -> std::io::Result<()> { res }) }) - .service(web::resource("/login").to(|| { - async { - "You are on /login. Go to src/redirect.rs to change this behavior." - } + .service(web::resource("/login").to(|| async { + "You are on /login. Go to src/redirect.rs to change this behavior." })) - .service(web::resource("/").to(|| { - async { "Hello, middleware! Check the console where the server is run." } + .service(web::resource("/").to(|| async { + "Hello, middleware! Check the console where the server is run." })) }) .bind("127.0.0.1:8080")? diff --git a/self-shutdown-route/Cargo.toml b/shutdown-server/Cargo.toml similarity index 75% rename from self-shutdown-route/Cargo.toml rename to shutdown-server/Cargo.toml index 4b3a1210..4eb27415 100644 --- a/self-shutdown-route/Cargo.toml +++ b/shutdown-server/Cargo.toml @@ -1,12 +1,13 @@ [package] -name = "self-shutdown-route" +name = "shutdown-server" version = "2.0.0" authors = ["Rob Ede "] edition = "2018" description = "Send a request to the server to shut it down" [dependencies] -actix-web = "2.0.0" actix-rt = "1.0.0" +actix-web = "2.0.0" env_logger = "0.7" futures = "0.3" +tokio = { version = "0.2.11", features = ["signal"] } diff --git a/self-shutdown-route/README.md b/shutdown-server/README.md similarity index 51% rename from self-shutdown-route/README.md rename to shutdown-server/README.md index 709069e2..cf061407 100644 --- a/self-shutdown-route/README.md +++ b/shutdown-server/README.md @@ -1,16 +1,19 @@ -# self-shutdown-route +# shutdown-server -> Demonstrates how to shutdown the web server using a route hosted by the server itself using channels. +Demonstrates how to shutdown the web server in a couple of ways: + +1. remotely, via http request + - Created in response to actix/actix-web#1315 + +2. sending a SIGINT signal to the server (control-c) -This technique can be easily modified to support shutting down the server using other kinds of external events. -Created in response to actix/actix-web#1315. ## Usage ### Running The Server ```bash -cargo run --bin self-shutdown-route +cargo run --bin shutdown-server # Starting 8 workers # Starting "actix-web-service-127.0.0.1:8080" service on 127.0.0.1:8080 diff --git a/self-shutdown-route/src/main.rs b/shutdown-server/src/main.rs similarity index 79% rename from self-shutdown-route/src/main.rs rename to shutdown-server/src/main.rs index a55feb9d..72cb0f7e 100644 --- a/self-shutdown-route/src/main.rs +++ b/shutdown-server/src/main.rs @@ -1,8 +1,7 @@ -use std::{sync::mpsc, thread}; - -use futures::executor; - use actix_web::{get, middleware, post, web, App, HttpResponse, HttpServer}; +use futures::executor; +use std::{sync::mpsc, thread}; +use tokio::signal::unix::{signal, SignalKind}; #[get("/hello")] async fn hello() -> &'static str { @@ -24,6 +23,7 @@ async fn main() -> std::io::Result<()> { // create a channel let (tx, rx) = mpsc::channel::<()>(); + let stopper = tx.clone(); let bind = "127.0.0.1:8080"; @@ -51,6 +51,15 @@ async fn main() -> std::io::Result<()> { executor::block_on(srv.stop(true)) }); + let mut stream = signal(SignalKind::interrupt())?; + actix_rt::spawn(async move { + loop { + stream.recv().await; + println!("\n*** SIGINT received. Stopping server, gracefully. ***\n"); + stopper.send(()).unwrap(); + } + }); + // run server server.await }