You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by jp...@apache.org on 2017/06/06 02:56:00 UTC
[trafficserver] 04/06: Improve graceful shutdown.
This is an automated email from the ASF dual-hosted git repository.
jpeach pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git
commit 693839a31e6e3839146f4d8aa80cd0a237a51db3
Author: James Peach <jp...@apache.org>
AuthorDate: Wed May 17 21:58:15 2017 -0700
Improve graceful shutdown.
Rather than sleeping in a signal handler, unify the signal handling
so that we always bounce the actual work up to the SignalContinuation.
Once we are there, then we can send a timed event to shutdown after the
timeot, or just cause a normal shutdown immediately.
On the exit path, stop the ProcessManager to keep the integration
tests happy.
---
proxy/Main.cc | 111 ++++++++++++++++++++++++++++++----------------------------
1 file changed, 58 insertions(+), 53 deletions(-)
diff --git a/proxy/Main.cc b/proxy/Main.cc
index 4242c6e..7512bfe 100644
--- a/proxy/Main.cc
+++ b/proxy/Main.cc
@@ -169,10 +169,7 @@ static int cmd_line_dprintf_level = 0; // default debug output level from ink_d
static int poll_timeout = -1; // No value set.
static int cmd_disable_freelist = 0;
-static int shutdown_timeout = 0;
-
-static volatile bool sigusr1_received = false;
-static volatile bool sigusr2_received = false;
+static volatile bool signal_received[NSIG];
// 1: delay listen, wait for cache.
// 0: Do not delay, start listen ASAP.
@@ -218,14 +215,25 @@ static ArgumentDescription argument_descriptions[] = {
{"accept_mss", '-', "MSS for client connections", "I", &accept_mss, nullptr, nullptr},
{"poll_timeout", 't', "poll timeout in milliseconds", "I", &poll_timeout, nullptr, nullptr},
HELP_ARGUMENT_DESCRIPTION(),
- VERSION_ARGUMENT_DESCRIPTION()};
+ VERSION_ARGUMENT_DESCRIPTION(),
+};
+
+struct AutoStopCont : public Continuation {
+ int
+ mainEvent(int /* event */, Event * /* e */)
+ {
+ pmgmt->stop();
+ shutdown_event_system = true;
+ delete this;
+ return EVENT_CONT;
+ }
+
+ AutoStopCont() : Continuation(new_ProxyMutex()) { SET_HANDLER(&AutoStopCont::mainEvent); }
+};
class SignalContinuation : public Continuation
{
public:
- char *end;
- char *snap;
-
SignalContinuation() : Continuation(new_ProxyMutex())
{
end = snap = nullptr;
@@ -235,36 +243,59 @@ public:
int
periodic(int /* event ATS_UNUSED */, Event * /* e ATS_UNUSED */)
{
- if (sigusr1_received) {
- sigusr1_received = false;
+ if (signal_received[SIGUSR1]) {
+ signal_received[SIGUSR1] = false;
// TODO: TS-567 Integrate with debugging allocators "dump" features?
ink_freelists_dump(stderr);
ResourceTracker::dump(stderr);
+
if (!end) {
end = (char *)sbrk(0);
}
+
if (!snap) {
snap = (char *)sbrk(0);
}
+
char *now = (char *)sbrk(0);
- // TODO: Use logging instead directly writing to stderr
- // This is not error condition at the first place
- // so why stderr?
- //
- fprintf(stderr, "sbrk 0x%" PRIu64 " from first %" PRIu64 " from last %" PRIu64 "\n", (uint64_t)((ptrdiff_t)now),
- (uint64_t)((ptrdiff_t)(now - end)), (uint64_t)((ptrdiff_t)(now - snap)));
+ Note("sbrk 0x%" PRIu64 " from first %" PRIu64 " from last %" PRIu64 "\n", (uint64_t)((ptrdiff_t)now),
+ (uint64_t)((ptrdiff_t)(now - end)), (uint64_t)((ptrdiff_t)(now - snap)));
snap = now;
- } else if (sigusr2_received) {
- sigusr2_received = false;
+ }
+
+ if (signal_received[SIGUSR2]) {
+ signal_received[SIGUSR2] = false;
+
Debug("log", "received SIGUSR2, reloading traffic.out");
+
// reload output logfile (file is usually called traffic.out)
diags->set_stdout_output(bind_stdout);
diags->set_stderr_output(bind_stderr);
}
+ if (signal_received[SIGTERM]) {
+ signal_received[SIGTERM] = false;
+
+ RecInt timeout = 0;
+ REC_ReadConfigInteger(timeout, "proxy.config.stop.shutdown_timeout");
+
+ if (timeout) {
+ http2_drain = true;
+ }
+
+ Debug("server", "received SIGTERM, shutting down in %" PRId64 "secs", timeout);
+
+ // Shutdown in `timeout` seconds (or now if that is 0).
+ eventProcessor.schedule_in(new AutoStopCont(), HRTIME_SECONDS(timeout));
+ }
+
return EVENT_CONT;
}
+
+private:
+ const char *end;
+ const char *snap;
};
class TrackerContinuation : public Continuation
@@ -431,14 +462,16 @@ init_memory_tracker(const char *config_var, RecDataT /* type ATS_UNUSED */, RecD
static void
proxy_signal_handler(int signo, siginfo_t *info, void *ctx)
{
+ if ((unsigned)signo < countof(signal_received)) {
+ signal_received[signo] = true;
+ }
+
+ // These signals are all handled by SignalContinuation.
switch (signo) {
case SIGUSR1:
- sigusr1_received = true;
- return;
case SIGUSR2:
- sigusr2_received = true;
- return;
case SIGHUP:
+ case SIGTERM:
return;
}
@@ -459,14 +492,6 @@ proxy_signal_handler(int signo, siginfo_t *info, void *ctx)
if (signal_is_crash(signo)) {
signal_crash_handler(signo, info, ctx);
}
-
- if (shutdown_timeout) {
- http2_drain = true;
- sleep(shutdown_timeout);
- }
-
- shutdown_event_system = true;
- sleep(1);
}
//
@@ -1287,26 +1312,6 @@ init_http_header()
hpack_huffman_init();
}
-struct AutoStopCont : public Continuation {
- int
- mainEvent(int event, Event *e)
- {
- (void)event;
- (void)e;
- ::exit(0);
- return 0;
- }
- AutoStopCont() : Continuation(new_ProxyMutex()) { SET_HANDLER(&AutoStopCont::mainEvent); }
-};
-
-static void
-run_AutoStop()
-{
- if (getenv("PROXY_AUTO_EXIT")) {
- eventProcessor.schedule_in(new AutoStopCont(), HRTIME_SECONDS(atoi(getenv("PROXY_AUTO_EXIT"))));
- }
-}
-
#if TS_HAS_TESTS
struct RegressionCont : public Continuation {
int initialized;
@@ -1687,8 +1692,6 @@ main(int /* argc ATS_UNUSED */, const char **argv)
::exit(0);
}
- REC_ReadConfigInteger(shutdown_timeout, "proxy.config.stop.shutdown_timeout");
-
// We need to do this early so we can initialize the Machine
// singleton, which depends on configuration values loaded in this.
// We want to initialize Machine as early as possible because it
@@ -1945,7 +1948,9 @@ main(int /* argc ATS_UNUSED */, const char **argv)
run_RegressionTest();
#endif
- run_AutoStop();
+ if (getenv("PROXY_AUTO_EXIT")) {
+ eventProcessor.schedule_in(new AutoStopCont(), HRTIME_SECONDS(atoi(getenv("PROXY_AUTO_EXIT"))));
+ }
}
#if !TS_USE_POSIX_CAP
--
To stop receiving notification emails like this one, please contact
"commits@trafficserver.apache.org" <co...@trafficserver.apache.org>.