nghttpx: Add --listener-disable-timeout option
This commit is contained in:
parent
0209b7c083
commit
822ec75814
21
src/shrpx.cc
21
src/shrpx.cc
|
@ -151,6 +151,11 @@ namespace {
|
|||
void evlistener_errorcb(evconnlistener *listener, void *ptr)
|
||||
{
|
||||
LOG(ERROR) << "Accepting incoming connection failed";
|
||||
|
||||
auto listener_handler = static_cast<ListenHandler*>(ptr);
|
||||
|
||||
listener_handler->disable_evlistener_temporary
|
||||
(&get_config()->listener_disable_timeout);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
|
@ -449,6 +454,8 @@ void graceful_shutdown_signal_cb(evutil_socket_t sig, short events, void *arg)
|
|||
LOG(INFO) << "Graceful shutdown signal received";
|
||||
}
|
||||
|
||||
worker_config->graceful_shutdown = true;
|
||||
|
||||
listener_handler->disable_evlistener();
|
||||
|
||||
// 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();
|
||||
|
||||
worker_config->graceful_shutdown = true;
|
||||
|
||||
listener_handler->graceful_shutdown_worker();
|
||||
}
|
||||
} // namespace
|
||||
|
@ -809,6 +814,7 @@ void fill_default_config()
|
|||
mod_config()->argc = 0;
|
||||
mod_config()->argv = nullptr;
|
||||
mod_config()->max_downstream_connections = 100;
|
||||
mod_config()->listener_disable_timeout = {0, 0};
|
||||
}
|
||||
} // namespace
|
||||
|
||||
|
@ -977,6 +983,12 @@ Timeout:
|
|||
connection.
|
||||
Default: )"
|
||||
<< 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>
|
||||
Specify proxy URI in the form
|
||||
http://[<USER>:<PASS>@]<PROXY>:<PORT>. If a
|
||||
|
@ -1297,6 +1309,7 @@ int main(int argc, char **argv)
|
|||
{"stream-write-timeout", required_argument, &flag, 61},
|
||||
{"no-location-rewrite", no_argument, &flag, 62},
|
||||
{"backend-connections-per-frontend", required_argument, &flag, 63},
|
||||
{"listener-disable-timeout", required_argument, &flag, 64},
|
||||
{nullptr, 0, nullptr, 0 }
|
||||
};
|
||||
|
||||
|
@ -1590,6 +1603,10 @@ int main(int argc, char **argv)
|
|||
cmdcfgs.emplace_back(SHRPX_OPT_BACKEND_CONNECTIONS_PER_FRONTEND,
|
||||
optarg);
|
||||
break;
|
||||
case 64:
|
||||
// --listener-disable-timeout
|
||||
cmdcfgs.emplace_back(SHRPX_OPT_LISTENER_DISABLE_TIMEOUT, optarg);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -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_BACKEND_CONNECTIONS_PER_FRONTEND[] =
|
||||
"backend-connections-per-frontend";
|
||||
const char SHRPX_OPT_LISTENER_DISABLE_TIMEOUT[] = "listener-disable-timeout";
|
||||
|
||||
namespace {
|
||||
Config *config = nullptr;
|
||||
|
@ -897,6 +898,13 @@ int parse_config(const char *opt, const char *optarg)
|
|||
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")) {
|
||||
LOG(WARNING) << "conf is ignored";
|
||||
|
||||
|
|
|
@ -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_NO_LOCATION_REWRITE[];
|
||||
extern const char SHRPX_OPT_BACKEND_CONNECTIONS_PER_FRONTEND[];
|
||||
extern const char SHRPX_OPT_LISTENER_DISABLE_TIMEOUT[];
|
||||
|
||||
union sockaddr_union {
|
||||
sockaddr sa;
|
||||
|
@ -173,6 +174,7 @@ struct Config {
|
|||
timeval stream_read_timeout;
|
||||
timeval stream_write_timeout;
|
||||
timeval downstream_idle_read_timeout;
|
||||
timeval listener_disable_timeout;
|
||||
std::unique_ptr<char[]> host;
|
||||
std::unique_ptr<char[]> private_key_file;
|
||||
std::unique_ptr<char[]> private_key_passwd;
|
||||
|
|
|
@ -45,6 +45,21 @@ using namespace nghttp2;
|
|||
|
||||
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,
|
||||
SSL_CTX *cl_ssl_ctx)
|
||||
: evbase_(evbase),
|
||||
|
@ -54,6 +69,8 @@ ListenHandler::ListenHandler(event_base *evbase, SSL_CTX *sv_ssl_ctx,
|
|||
(evbase, get_config()->worker_rate_limit_cfg)),
|
||||
evlistener4_(nullptr),
|
||||
evlistener6_(nullptr),
|
||||
evlistener_disable_timerev_(evtimer_new(evbase,
|
||||
evlistener_disable_cb, this)),
|
||||
worker_stat_(util::make_unique<WorkerStat>()),
|
||||
num_worker_shutdown_(0),
|
||||
worker_round_robin_cnt_(0)
|
||||
|
@ -295,6 +312,17 @@ evconnlistener* ListenHandler::get_evlistener6() const
|
|||
return evlistener6_;
|
||||
}
|
||||
|
||||
void ListenHandler::enable_evlistener()
|
||||
{
|
||||
if(evlistener4_) {
|
||||
evconnlistener_enable(evlistener4_);
|
||||
}
|
||||
|
||||
if(evlistener6_) {
|
||||
evconnlistener_enable(evlistener6_);
|
||||
}
|
||||
}
|
||||
|
||||
void ListenHandler::disable_evlistener()
|
||||
{
|
||||
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 {
|
||||
void perform_accept_pending_connection(ListenHandler *listener_handler,
|
||||
evconnlistener *listener)
|
||||
|
|
|
@ -73,7 +73,9 @@ public:
|
|||
evconnlistener* get_evlistener4() const;
|
||||
void set_evlistener6(evconnlistener *evlistener6);
|
||||
evconnlistener* get_evlistener6() const;
|
||||
void enable_evlistener();
|
||||
void disable_evlistener();
|
||||
void disable_evlistener_temporary(const timeval *timeout);
|
||||
void accept_pending_connection();
|
||||
void graceful_shutdown_worker();
|
||||
void join_worker();
|
||||
|
@ -92,6 +94,7 @@ private:
|
|||
bufferevent_rate_limit_group *rate_limit_group_;
|
||||
evconnlistener *evlistener4_;
|
||||
evconnlistener *evlistener6_;
|
||||
event *evlistener_disable_timerev_;
|
||||
std::unique_ptr<WorkerStat> worker_stat_;
|
||||
size_t num_worker_shutdown_;
|
||||
unsigned int worker_round_robin_cnt_;
|
||||
|
|
Loading…
Reference in New Issue