pub struct Server<F> { /* private fields */ }
Expand description
A listening server.
This struct is the more manual server creation API of rouille and can be used as an alternative
to the start_server
function.
The start_server
function is just a shortcut for Server::new
followed with run
. See the
documentation of the start_server
function for more details about the handler.
§Example
use rouille::Server;
use rouille::Response;
let server = Server::new("localhost:0", |request| {
Response::text("hello world")
}).unwrap();
println!("Listening on {:?}", server.server_addr());
server.run();
Implementations§
Source§impl<F> Server<F>
impl<F> Server<F>
Sourcepub fn new<A>(
addr: A,
handler: F,
) -> Result<Server<F>, Box<dyn Error + Send + Sync + 'static>>where
A: ToSocketAddrs,
pub fn new<A>(
addr: A,
handler: F,
) -> Result<Server<F>, Box<dyn Error + Send + Sync + 'static>>where
A: ToSocketAddrs,
Builds a new Server
object.
After this function returns, the HTTP server is listening.
Returns an error if there was an error while creating the listening socket, for example if the port is already in use.
Sourcepub fn pool_size(self, pool_size: usize) -> Self
pub fn pool_size(self, pool_size: usize) -> Self
Use a ThreadPool
of the given size to process requests
pool_size
must be greater than zero or this function will panic.
Sourcepub fn server_addr(&self) -> SocketAddr
pub fn server_addr(&self) -> SocketAddr
Returns the address of the listening socket.
Sourcepub fn run(self)
pub fn run(self)
Runs the server forever, or until the listening socket is somehow force-closed by the operating system.
Sourcepub fn poll(&self)
pub fn poll(&self)
Processes all the client requests waiting to be processed, then returns.
This function executes very quickly, as each client requests that needs to be processed is processed in a separate thread.
Sourcepub fn stoppable(self) -> (JoinHandle<()>, Sender<()>)
pub fn stoppable(self) -> (JoinHandle<()>, Sender<()>)
Creates a new thread for the server that can be gracefully stopped later.
This function returns a tuple of a JoinHandle
and a Sender
.
You must call JoinHandle::join()
otherwise the server will not run until completion.
The server can be stopped at will by sending it an empty ()
message from another thread.
There may be a maximum of a 1 second delay between sending the stop message and the server
stopping. This delay may be shortened in future.
use std::thread;
use std::time::Duration;
use rouille::Server;
use rouille::Response;
let server = Server::new("localhost:0", |request| {
Response::text("hello world")
}).unwrap();
println!("Listening on {:?}", server.server_addr());
let (handle, sender) = server.stoppable();
// Stop the server in 3 seconds
thread::spawn(move || {
thread::sleep(Duration::from_secs(3));
sender.send(()).unwrap();
});
// Block the main thread until the server is stopped
handle.join().unwrap();
Sourcepub fn poll_timeout(&self, dur: Duration)
pub fn poll_timeout(&self, dur: Duration)
Same as poll()
but blocks for at most duration
before returning.
This function can be used implement a custom server loop in a more CPU-efficient manner
than calling poll
.
§Example
use rouille::Server;
use rouille::Response;
let server = Server::new("localhost:0", |request| {
Response::text("hello world")
}).unwrap();
println!("Listening on {:?}", server.server_addr());
loop {
server.poll_timeout(std::time::Duration::from_millis(100));
}
Sourcepub fn join(&self)
pub fn join(&self)
Waits for all in-flight requests to be processed. This is useful for implementing a graceful shutdown.
Note: new connections may still be accepted while we wait, and this function does not guarantee to wait for those new requests. To implement a graceful shutdown or a clean rolling-update, the following approach should be used:
-
Stop routing requests to this server. For a rolling update, requests should be routed to the new instance. This logic typically sits outside of your application.
-
Drain the queue of incoming connections by calling
poll_timeout
with a short timeout. -
Wait for in-flight requests to be processed by using this method.
§Example
// Accept connections until we receive a SIGTERM
while !is_stopping() {
server.poll_timeout(Duration::from_millis(100));
}
// We received a SIGTERM, but there still may be some queued connections,
// so wait for them to be accepted.
println!("Shutting down gracefully...");
server.poll_timeout(Duration::from_millis(100));
// We can expect there to be no more queued connections now, but slow requests
// may still be in-flight, so wait for them to finish.
server.join();