This commit is contained in:
ivegotasthma 2018-03-17 15:48:38 +00:00 committed by GitHub
commit c30e5e9958
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 87 additions and 7 deletions

View File

@ -124,5 +124,6 @@ members = [
"examples/websocket-chat",
"examples/web-cors/backend",
"examples/unix-socket",
"examples/catflap",
"tools/wsload/",
]

View File

@ -0,0 +1,10 @@
[package]
name = "catflap"
version = "0.1.0"
authors = ["ivegotasthma <ivegotasthma@protonmail.com>"]
workspace = "../.."
[dependencies]
env_logger = "0.5"
actix = "0.5"
actix-web = { path = "../../" }

View File

@ -0,0 +1,24 @@
# catflap
There is the utility [cargo-watch](https://github.com/passcod/cargo-watch) which rebuilds your project when it notices
there are changed files. This is very useful when writing web server and you want to have a fast edit, compile, run
cycle.
The problem is that when you're using this for a web server the socket that the server uses might still be in use
from the previous run. This makes `cargo-watch` crash. The solution, from the author of `cargo-watch` is `catflap`. It's
another utility that takes ownership of sockets and passes them the program you're running with cargo watch.
To be able to use the sockets provided by `catflap` you need to read the file descriptor from the environment variable
`LISTEN_FD`.
This example will how you how to do that on a hello world.
By default the server will be running on port `5000`, unless you pass the flag `-p 8080` to catflap. Then it will run on
port `8080`
## Usage
```bash
cd actix-web/examples/catflap
catflap -- cargo watch -x run
# Started http server: 127.0.0.1:8080
```

View File

@ -0,0 +1,29 @@
extern crate actix;
extern crate actix_web;
extern crate env_logger;
use actix_web::*;
fn index(_req: HttpRequest) -> &'static str {
"hello, world"
}
fn main() {
::std::env::set_var("RUST_LOG", "actix_web=info");
let _ = env_logger::init();
let sys = actix::System::new("catflap-example");
let fd = std::env::var("LISTEN_FD").ok()
.and_then(|fd| fd.parse().ok())
.expect("couldn't get LISTEN_FD env variable");
let _addr = HttpServer::new(
|| Application::new()
.resource("/", |r| r.f(index)))
.bind_socket(fd).unwrap()
.start();
println!("Started http server.");
let _ = sys.run();
}

View File

@ -19,7 +19,7 @@ diesel migration run
# if ubuntu : sudo apt-get install libsqlite3-dev
# if fedora : sudo dnf install libsqlite3x-devel
cd actix-web/examples/diesel
cargo run (or ``cargo watch -x run``)
cargo run (or see examples/catflap for rebuilding and redeploying on file change)
# Started http server: 127.0.0.1:8080
```

View File

@ -6,7 +6,7 @@ Juniper integration for Actix web
```bash
cd actix-web/examples/juniper
cargo run (or ``cargo watch -x run``)
cargo run (or see examples/catflap for rebuilding and redeploying on file change)
# Started http server: 127.0.0.1:8080
```

View File

@ -8,7 +8,7 @@ Multipart's `Getting Started` guide for Actix web
```bash
cd actix-web/examples/multipart
cargo run (or ``cargo watch -x run``)
cargo run (or see examples/catflap for rebuilding and redeploying on file change)
# Started http server: 127.0.0.1:8080
```

View File

@ -8,7 +8,7 @@ Minimal example of using the template [tera](https://github.com/Keats/tera) that
```bash
cd actix-web/examples/template_tera
cargo run (or ``cargo watch -x run``)
cargo run (or see examples/catflap for rebuilding and redeploying on file change)
# Started http server: 127.0.0.1:8080
```

View File

@ -6,7 +6,7 @@
```bash
cd actix-web/examples/tls
cargo run (or ``cargo watch -x run``)
cargo run (or see examples/catflap for rebuilding and redeploying on file change)
# Started http server: 127.0.0.1:8443
```

View File

@ -18,6 +18,9 @@ use native_tls::TlsAcceptor;
#[cfg(feature="alpn")]
use openssl::ssl::{AlpnError, SslAcceptorBuilder};
#[cfg(target_family="unix")]
use std::os::unix::io::{FromRawFd, RawFd};
use helpers;
use super::{IntoHttpHandler, IoStream, KeepAlive};
use super::{PauseServer, ResumeServer, StopServer};
@ -192,9 +195,22 @@ impl<H> HttpServer<H> where H: IntoHttpHandler + 'static
self
}
#[cfg(target_family="unix")]
/// The socket to bind to
///
/// To bind multiple sockets this method can be called multiple times.
pub fn bind_socket(mut self, sock: RawFd) -> io::Result<Self> {
unsafe {
let lst = net::TcpListener::from_raw_fd(sock);
self.sockets.insert(lst.local_addr().unwrap(), lst);
}
Ok(self)
}
/// The socket address to bind
///
/// To mind multiple addresses this method can be call multiple times.
/// To bind multiple addresses this method can be called multiple times.
pub fn bind<S: net::ToSocketAddrs>(mut self, addr: S) -> io::Result<Self> {
let mut err = None;
let mut succ = false;