More graceful stop of nghttp2::asio_http2::server::http2

Explicit io_service::stop() will prevent running streams from
finishing their task. That means if there are already reposnes
that we have called end(std::string) on them and they have not
finished sending back their data, they will be closed with a
NGHTTP2_INTERNAL_ERROR
Instead, we can stop accepting connections and destroy all
io_service::work objects to signals end of work.
This commit is contained in:
Amir Pakdel 2017-02-09 23:34:19 -05:00
parent 8f888b29bd
commit 1c31213aef
3 changed files with 20 additions and 2 deletions

View File

@ -75,13 +75,18 @@ void io_service_pool::join() {
}
}
void io_service_pool::stop() {
void io_service_pool::force_stop() {
// Explicitly stop all io_services.
for (auto &iosv : io_services_) {
iosv->stop();
}
}
void io_service_pool::stop() {
// Destroy all work objects to signals end of work
work_.clear();
}
boost::asio::io_service &io_service_pool::get_io_service() {
// Use a round-robin scheme to choose the next io_service to use.
auto &io_service = *io_services_[next_io_service_];

View File

@ -62,6 +62,9 @@ public:
void run(bool asynchronous = false);
/// Stop all io_service objects in the pool.
void force_stop();
/// Destroy all work objects to signals end of work
void stop();
/// Join on all io_service objects in the pool.

View File

@ -124,6 +124,11 @@ boost::system::error_code server::bind_and_listen(boost::system::error_code &ec,
void server::start_accept(boost::asio::ssl::context &tls_context,
tcp::acceptor &acceptor, serve_mux &mux) {
if (!acceptor.is_open()) {
return;
}
auto new_connection = std::make_shared<connection<ssl_socket>>(
mux, tls_handshake_timeout_, read_timeout_,
io_service_pool_.get_io_service(), tls_context);
@ -158,6 +163,11 @@ void server::start_accept(boost::asio::ssl::context &tls_context,
}
void server::start_accept(tcp::acceptor &acceptor, serve_mux &mux) {
if (!acceptor.is_open()) {
return;
}
auto new_connection = std::make_shared<connection<tcp::socket>>(
mux, tls_handshake_timeout_, read_timeout_,
io_service_pool_.get_io_service());
@ -177,10 +187,10 @@ void server::start_accept(tcp::acceptor &acceptor, serve_mux &mux) {
}
void server::stop() {
io_service_pool_.stop();
for (auto &acceptor : acceptors_) {
acceptor.close();
}
io_service_pool_.stop();
}
void server::join() { io_service_pool_.join(); }