diff options
author | James E. King III <jking@apache.org> | 2018-03-16 16:07:42 -0400 |
---|---|---|
committer | James E. King III <jking@apache.org> | 2018-03-19 14:38:49 -0400 |
commit | 9bea32f73c36a8f53a45e818cfafe81b6fefefae (patch) | |
tree | 9598fe6b03c4b22d7baf84607bbabbbda1d66bc0 /lib/d | |
parent | 02fbe0ecc795881fe11a447d0a5f6f2f656f7bb4 (diff) | |
download | thrift-9bea32f73c36a8f53a45e818cfafe81b6fefefae.tar.gz |
THRIFT-4515: cross server test improvement: graceful test server shutdown
This closes #1509
Diffstat (limited to 'lib/d')
-rw-r--r-- | lib/d/test/thrift_test_server.d | 58 |
1 files changed, 55 insertions, 3 deletions
diff --git a/lib/d/test/thrift_test_server.d b/lib/d/test/thrift_test_server.d index 71ab9175d..b582253c7 100644 --- a/lib/d/test/thrift_test_server.d +++ b/lib/d/test/thrift_test_server.d @@ -16,8 +16,11 @@ * specific language governing permissions and limitations * under the License. */ + module thrift_test_server; +import core.stdc.errno : errno; +import core.stdc.signal : signal, sigfn_t, SIGINT, SIG_DFL, SIG_ERR; import core.thread : dur, Thread; import std.algorithm; import std.exception : enforce; @@ -40,6 +43,7 @@ import thrift.transport.buffered; import thrift.transport.framed; import thrift.transport.http; import thrift.transport.ssl; +import thrift.util.cancellation; import thrift.util.hashset; import test_utils; @@ -205,14 +209,44 @@ private: bool trace_; } +shared(bool) gShutdown = false; + +nothrow @nogc extern(C) void handleSignal(int sig) { + gShutdown = true; +} + +// Runs a thread that waits for shutdown to be +// signaled and then triggers cancellation, +// causing the server to stop. While we could +// use a signalfd for this purpose, we are instead +// opting for a busy waiting scheme for maximum +// portability since signalfd is a linux thing. + +class ShutdownThread : Thread { + this(TCancellationOrigin cancellation) { + cancellation_ = cancellation; + super(&run); + } + +private: + void run() { + while (!gShutdown) { + Thread.sleep(dur!("msecs")(25)); + } + cancellation_.trigger(); + } + + TCancellationOrigin cancellation_; +} + void main(string[] args) { ushort port = 9090; ServerType serverType; ProtocolType protocolType; size_t numIOThreads = 1; TransportType transportType; - bool ssl; - bool trace; + bool ssl = false; + bool trace = true; size_t taskPoolSize = totalCPUs; getopt(args, "port", &port, "protocol", &protocolType, "server-type", @@ -279,8 +313,26 @@ void main(string[] args) { auto server = createServer(serverType, numIOThreads, taskPoolSize, processor, serverSocket, transportFactory, protocolFactory); + // Set up SIGINT signal handling + sigfn_t oldHandler = signal(SIGINT, &handleSignal); + enforce(oldHandler != SIG_ERR, + "Could not replace the SIGINT signal handler: errno {0}".format(errno())); + + // Set up a server cancellation trigger + auto cancel = new TCancellationOrigin(); + + // Set up a listener for the shutdown condition - this will + // wake up when the signal occurs and trigger cancellation. + auto shutdown = new ShutdownThread(cancel); + shutdown.start(); + + // Serve from this thread; the signal will stop the server + // and control will return here writefln("Starting %s/%s %s ThriftTest server %son port %s...", protocolType, transportType, serverType, ssl ? "(using SSL) ": "", port); - server.serve(); + server.serve(cancel); + shutdown.join(); + signal(SIGINT, SIG_DFL); + writeln("done."); } |