Open fivethousand opened 3 years ago
Start server/system in a child process. Sockets and pipes are closed when the child process terminates.
actix_rt::System
does not actually control the socket accept thread. You can use the server handle to send stop command to it.
This is an example.
use actix_web::{middleware, App, HttpServer};
pub fn main() -> std::io::Result<()> {
let mut system = actix_web::rt::System::new("main");
loop {
let server = system.block_on(async move {
HttpServer::new(move || App::new().wrap(middleware::Logger::default()))
.bind("127.0.0.1:8080")
.unwrap()
.run()
});
server.stop(true);
actix_web::rt::System::current().stop();
}
}
Also one thing to notice is that Server::stop would also call System::current().stop() with a delay. So you can remove the extra explict call and it would also work.
Expected Behavior
Stopping server/system closes all sockets and pipes.
Current Behavior
Stopping the server/system (without exiting the process) leaves a number of sockets and pipes open. Therefore, restarting the server increases the number of open sockets and pipes.
Steps to Reproduce
ls -l /proc/[PID]/fd
contains 7 sockets and 28 pipes in the first iteration. PressingCtrl+C
shuts down the server (and the system) and proceeds to the next iteration. This timels -l /proc/[PID]/fd
contains 11 sockets and 30 pipes.Moving
let mut system = ...
into the loop avoids increasing the number of open sockets, but at the same time increases the number of open pipes by 22 in each iteration.Context
I am trying to restart the server to change routes/handlers. Since the router is read-only, restarting the server is the only solution that does not involve writing a custom router.
Besides the issue reported here, a simple solution based on https://github.com/actix/examples/tree/master/shutdown-server (slightly extended to differentiate stop/restart) works well.
Your Environment