nghttpx: Add --listener-disable-timeout option

This commit is contained in:
Tatsuhiro Tsujikawa 2014-08-27 22:34:00 +09:00
parent 0209b7c083
commit 822ec75814
5 changed files with 78 additions and 2 deletions

View File

@ -151,6 +151,11 @@ namespace {
void evlistener_errorcb(evconnlistener *listener, void *ptr) void evlistener_errorcb(evconnlistener *listener, void *ptr)
{ {
LOG(ERROR) << "Accepting incoming connection failed"; LOG(ERROR) << "Accepting incoming connection failed";
auto listener_handler = static_cast<ListenHandler*>(ptr);
listener_handler->disable_evlistener_temporary
(&get_config()->listener_disable_timeout);
} }
} // namespace } // namespace
@ -449,6 +454,8 @@ void graceful_shutdown_signal_cb(evutil_socket_t sig, short events, void *arg)
LOG(INFO) << "Graceful shutdown signal received"; LOG(INFO) << "Graceful shutdown signal received";
} }
worker_config->graceful_shutdown = true;
listener_handler->disable_evlistener(); listener_handler->disable_evlistener();
// After disabling accepting new connection, disptach incoming // After disabling accepting new connection, disptach incoming
@ -456,8 +463,6 @@ void graceful_shutdown_signal_cb(evutil_socket_t sig, short events, void *arg)
listener_handler->accept_pending_connection(); listener_handler->accept_pending_connection();
worker_config->graceful_shutdown = true;
listener_handler->graceful_shutdown_worker(); listener_handler->graceful_shutdown_worker();
} }
} // namespace } // namespace
@ -809,6 +814,7 @@ void fill_default_config()
mod_config()->argc = 0; mod_config()->argc = 0;
mod_config()->argv = nullptr; mod_config()->argv = nullptr;
mod_config()->max_downstream_connections = 100; mod_config()->max_downstream_connections = 100;
mod_config()->listener_disable_timeout = {0, 0};
} }
} // namespace } // namespace
@ -977,6 +983,12 @@ Timeout:
connection. connection.
Default: )" Default: )"
<< get_config()->downstream_idle_read_timeout.tv_sec << R"( << get_config()->downstream_idle_read_timeout.tv_sec << R"(
--listener-disable-timeout=<SEC>
After accepting connection failed, connection
listener is disabled for a given time in seconds.
Specifying 0 disables this feature.
Default: )"
<< get_config()->listener_disable_timeout.tv_sec << R"(
--backend-http-proxy-uri=<URI> --backend-http-proxy-uri=<URI>
Specify proxy URI in the form Specify proxy URI in the form
http://[<USER>:<PASS>@]<PROXY>:<PORT>. If a http://[<USER>:<PASS>@]<PROXY>:<PORT>. If a
@ -1297,6 +1309,7 @@ int main(int argc, char **argv)
{"stream-write-timeout", required_argument, &flag, 61}, {"stream-write-timeout", required_argument, &flag, 61},
{"no-location-rewrite", no_argument, &flag, 62}, {"no-location-rewrite", no_argument, &flag, 62},
{"backend-connections-per-frontend", required_argument, &flag, 63}, {"backend-connections-per-frontend", required_argument, &flag, 63},
{"listener-disable-timeout", required_argument, &flag, 64},
{nullptr, 0, nullptr, 0 } {nullptr, 0, nullptr, 0 }
}; };
@ -1590,6 +1603,10 @@ int main(int argc, char **argv)
cmdcfgs.emplace_back(SHRPX_OPT_BACKEND_CONNECTIONS_PER_FRONTEND, cmdcfgs.emplace_back(SHRPX_OPT_BACKEND_CONNECTIONS_PER_FRONTEND,
optarg); optarg);
break; break;
case 64:
// --listener-disable-timeout
cmdcfgs.emplace_back(SHRPX_OPT_LISTENER_DISABLE_TIMEOUT, optarg);
break;
default: default:
break; break;
} }

View File

@ -131,6 +131,7 @@ const char SHRPX_OPT_WORKER_FRONTEND_CONNECTIONS[] =
const char SHRPX_OPT_NO_LOCATION_REWRITE[] = "no-location-rewrite"; const char SHRPX_OPT_NO_LOCATION_REWRITE[] = "no-location-rewrite";
const char SHRPX_OPT_BACKEND_CONNECTIONS_PER_FRONTEND[] = const char SHRPX_OPT_BACKEND_CONNECTIONS_PER_FRONTEND[] =
"backend-connections-per-frontend"; "backend-connections-per-frontend";
const char SHRPX_OPT_LISTENER_DISABLE_TIMEOUT[] = "listener-disable-timeout";
namespace { namespace {
Config *config = nullptr; Config *config = nullptr;
@ -897,6 +898,13 @@ int parse_config(const char *opt, const char *optarg)
return 0; return 0;
} }
if(util::strieq(opt, SHRPX_OPT_LISTENER_DISABLE_TIMEOUT)) {
timeval tv = {strtol(optarg, nullptr, 10), 0};
mod_config()->listener_disable_timeout = tv;
return 0;
}
if(util::strieq(opt, "conf")) { if(util::strieq(opt, "conf")) {
LOG(WARNING) << "conf is ignored"; LOG(WARNING) << "conf is ignored";

View File

@ -120,6 +120,7 @@ extern const char SHRPX_OPT_ADD_RESPONSE_HEADER[];
extern const char SHRPX_OPT_WORKER_FRONTEND_CONNECTIONS[]; extern const char SHRPX_OPT_WORKER_FRONTEND_CONNECTIONS[];
extern const char SHRPX_OPT_NO_LOCATION_REWRITE[]; extern const char SHRPX_OPT_NO_LOCATION_REWRITE[];
extern const char SHRPX_OPT_BACKEND_CONNECTIONS_PER_FRONTEND[]; extern const char SHRPX_OPT_BACKEND_CONNECTIONS_PER_FRONTEND[];
extern const char SHRPX_OPT_LISTENER_DISABLE_TIMEOUT[];
union sockaddr_union { union sockaddr_union {
sockaddr sa; sockaddr sa;
@ -173,6 +174,7 @@ struct Config {
timeval stream_read_timeout; timeval stream_read_timeout;
timeval stream_write_timeout; timeval stream_write_timeout;
timeval downstream_idle_read_timeout; timeval downstream_idle_read_timeout;
timeval listener_disable_timeout;
std::unique_ptr<char[]> host; std::unique_ptr<char[]> host;
std::unique_ptr<char[]> private_key_file; std::unique_ptr<char[]> private_key_file;
std::unique_ptr<char[]> private_key_passwd; std::unique_ptr<char[]> private_key_passwd;

View File

@ -45,6 +45,21 @@ using namespace nghttp2;
namespace shrpx { namespace shrpx {
namespace {
void evlistener_disable_cb(evutil_socket_t fd, short events, void *arg)
{
auto listener_handler = static_cast<ListenHandler*>(arg);
// If we are in graceful shutdown period, we must not enable
// evlisteners again.
if(worker_config->graceful_shutdown) {
return;
}
listener_handler->enable_evlistener();
}
} // namespace
ListenHandler::ListenHandler(event_base *evbase, SSL_CTX *sv_ssl_ctx, ListenHandler::ListenHandler(event_base *evbase, SSL_CTX *sv_ssl_ctx,
SSL_CTX *cl_ssl_ctx) SSL_CTX *cl_ssl_ctx)
: evbase_(evbase), : evbase_(evbase),
@ -54,6 +69,8 @@ ListenHandler::ListenHandler(event_base *evbase, SSL_CTX *sv_ssl_ctx,
(evbase, get_config()->worker_rate_limit_cfg)), (evbase, get_config()->worker_rate_limit_cfg)),
evlistener4_(nullptr), evlistener4_(nullptr),
evlistener6_(nullptr), evlistener6_(nullptr),
evlistener_disable_timerev_(evtimer_new(evbase,
evlistener_disable_cb, this)),
worker_stat_(util::make_unique<WorkerStat>()), worker_stat_(util::make_unique<WorkerStat>()),
num_worker_shutdown_(0), num_worker_shutdown_(0),
worker_round_robin_cnt_(0) worker_round_robin_cnt_(0)
@ -295,6 +312,17 @@ evconnlistener* ListenHandler::get_evlistener6() const
return evlistener6_; return evlistener6_;
} }
void ListenHandler::enable_evlistener()
{
if(evlistener4_) {
evconnlistener_enable(evlistener4_);
}
if(evlistener6_) {
evconnlistener_enable(evlistener6_);
}
}
void ListenHandler::disable_evlistener() void ListenHandler::disable_evlistener()
{ {
if(evlistener4_) { if(evlistener4_) {
@ -306,6 +334,24 @@ void ListenHandler::disable_evlistener()
} }
} }
void ListenHandler::disable_evlistener_temporary(const timeval *timeout)
{
int rv;
if(timeout->tv_sec == 0 ||
evtimer_pending(evlistener_disable_timerev_, nullptr)) {
return;
}
disable_evlistener();
rv = evtimer_add(evlistener_disable_timerev_, timeout);
if(rv < 0) {
LOG(ERROR) << "evtimer_add for evlistener_disable_timerev_ failed";
}
}
namespace { namespace {
void perform_accept_pending_connection(ListenHandler *listener_handler, void perform_accept_pending_connection(ListenHandler *listener_handler,
evconnlistener *listener) evconnlistener *listener)

View File

@ -73,7 +73,9 @@ public:
evconnlistener* get_evlistener4() const; evconnlistener* get_evlistener4() const;
void set_evlistener6(evconnlistener *evlistener6); void set_evlistener6(evconnlistener *evlistener6);
evconnlistener* get_evlistener6() const; evconnlistener* get_evlistener6() const;
void enable_evlistener();
void disable_evlistener(); void disable_evlistener();
void disable_evlistener_temporary(const timeval *timeout);
void accept_pending_connection(); void accept_pending_connection();
void graceful_shutdown_worker(); void graceful_shutdown_worker();
void join_worker(); void join_worker();
@ -92,6 +94,7 @@ private:
bufferevent_rate_limit_group *rate_limit_group_; bufferevent_rate_limit_group *rate_limit_group_;
evconnlistener *evlistener4_; evconnlistener *evlistener4_;
evconnlistener *evlistener6_; evconnlistener *evlistener6_;
event *evlistener_disable_timerev_;
std::unique_ptr<WorkerStat> worker_stat_; std::unique_ptr<WorkerStat> worker_stat_;
size_t num_worker_shutdown_; size_t num_worker_shutdown_;
unsigned int worker_round_robin_cnt_; unsigned int worker_round_robin_cnt_;