Advanced servers support clean shutdown via SIGINT or SIGTERM

fix #1026
This commit is contained in:
Vinnie Falco
2018-02-21 12:41:54 -08:00
parent a4714746dc
commit 10ce0283c2
6 changed files with 66 additions and 23 deletions

View File

@@ -3,6 +3,7 @@ Version 158:
* Tidy up end_of_stream javadoc * Tidy up end_of_stream javadoc
* Tidy up websocket docs * Tidy up websocket docs
* Examples set reuse_address(true) * Examples set reuse_address(true)
* Advanced servers support clean shutdown via SIGINT or SIGTERM
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------

View File

@@ -28,7 +28,7 @@
[template source_file[path] '''<ulink url="../../'''[path]'''">'''[path]'''</ulink>'''] [template source_file[path] '''<ulink url="../../'''[path]'''">'''[path]'''</ulink>''']
[template include_file[path][^<'''<ulink url="../../../../'''[path]'''">'''[path]'''</ulink>'''>]] [template include_file[path][^<'''<ulink url="../../../../'''[path]'''">'''[path]'''</ulink>'''>]]
[template issue[n] '''(<ulink url="https://github.com/boostorg/beast/issues/'''[n]'''">#'''[n]'''</ulink>)'''] [template issue[n] '''<ulink url="https://github.com/boostorg/beast/issues/'''[n]'''">#'''[n]'''</ulink>''']
[def __N3747__ [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3747.pdf [*N3747]]] [def __N3747__ [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3747.pdf [*N3747]]]
[def __NetTS__ [@http://cplusplus.github.io/networking-ts/draft.pdf [*Networking.TS]]] [def __NetTS__ [@http://cplusplus.github.io/networking-ts/draft.pdf [*Networking.TS]]]

View File

@@ -180,7 +180,9 @@ and illustrate the implementation of advanced features.
[HTTP pipelining] [HTTP pipelining]
[Asynchronous timeouts] [Asynchronous timeouts]
[Dual protocols: HTTP and WebSocket] [Dual protocols: HTTP and WebSocket]
[WebSocket use idle ping for timeout]]] [WebSocket use idle ping for timeout]
[Clean exit via SIGINT (CTRL+C) or SIGTERM (kill)]
]]
[[example_src example/advanced/server/advanced_server.cpp advanced_server.cpp]] [[example_src example/advanced/server/advanced_server.cpp advanced_server.cpp]]
][ ][
[Advanced, flex (plain + SSL)] [Advanced, flex (plain + SSL)]
@@ -189,7 +191,9 @@ and illustrate the implementation of advanced features.
[Asynchronous timeouts] [Asynchronous timeouts]
[Dual protocols: HTTP and WebSocket] [Dual protocols: HTTP and WebSocket]
[WebSocket use idle ping for timeout] [WebSocket use idle ping for timeout]
[Flexible ports: plain and SSL on the same port]]] [Flexible ports: plain and SSL on the same port]
[Clean exit via SIGINT (CTRL+C) or SIGTERM (kill)]
]]
[[example_src example/advanced/server-flex/advanced_server_flex.cpp advanced_server_flex.cpp]] [[example_src example/advanced/server-flex/advanced_server_flex.cpp advanced_server_flex.cpp]]
]] ]]

View File

@@ -20,9 +20,9 @@ to update to the latest Boost release.
* Move-only completion handlers are supported throughout the library * Move-only completion handlers are supported throughout the library
* [issue 899] Advanced server examples support idle websocket pings and timeouts * ([issue 899]) Advanced server examples support idle websocket pings and timeouts
* [issue 849] WebSocket permessage-deflate support is now a compile-time * ([issue 849]) WebSocket permessage-deflate support is now a compile-time
feature. This adds an additional `bool` template parameter to feature. This adds an additional `bool` template parameter to
[link beast.ref.boost__beast__websocket__stream `websocket::stream`] [link beast.ref.boost__beast__websocket__stream `websocket::stream`]
When `deflateSupported` is `true`, the stream will be capable of When `deflateSupported` is `true`, the stream will be capable of
@@ -34,7 +34,7 @@ to update to the latest Boost release.
will be excluded from function instantiations. Programs which set will be excluded from function instantiations. Programs which set
`deflateSupported` to `false` when instantiating streams will be smaller. `deflateSupported` to `false` when instantiating streams will be smaller.
* [issue 949] WebSocket error codes are revised. New * ([issue 949]) WebSocket error codes are revised. New
[link beast.ref.boost__beast__websocket__error error codes] [link beast.ref.boost__beast__websocket__error error codes]
are added for more fine-grained failure outcomes. Messages for error are added for more fine-grained failure outcomes. Messages for error
codes are more verbose to help pinpoint the problem. Error codes are codes are more verbose to help pinpoint the problem. Error codes are
@@ -56,11 +56,11 @@ to update to the latest Boost release.
[*Improvements] [*Improvements]
* [issue 857] * ([issue 857])
[link beast.ref.boost__beast__http__basic_fields `http::basic_fields`] [link beast.ref.boost__beast__http__basic_fields `http::basic_fields`]
uses less storage uses less storage
* [issue 894] * ([issue 894])
[link beast.ref.boost__beast__http__basic_fields `http::basic_fields`] [link beast.ref.boost__beast__http__basic_fields `http::basic_fields`]
exception specifiers are provided exception specifiers are provided
@@ -68,45 +68,47 @@ to update to the latest Boost release.
* Add [include_file boost/beast/websocket/stream_fwd.hpp] * Add [include_file boost/beast/websocket/stream_fwd.hpp]
* [issue 955] The asynchronous SSL detector example uses a stackless coroutine * ([issue 955]) The asynchronous SSL detector example uses a stackless coroutine
* [link beast.ref.boost__beast__bind_handler `bind_handler`] * [link beast.ref.boost__beast__bind_handler `bind_handler`]
works with boost placeholders works with boost placeholders
* Examples set `reuse_address(true)` * Examples set `reuse_address(true)`
* ([issue 1026]) Advanced servers support clean shutdown via SIGINT or SIGTERM
[*Fixes] [*Fixes]
* Fix "warning: const type qualifier on return type has no effect" * Fix "warning: const type qualifier on return type has no effect"
* [issue 916] Tidy up `ssl_stream` special members in * ([issue 916]) Tidy up `ssl_stream` special members in
[source_file example/common/ssl_stream.hpp] [source_file example/common/ssl_stream.hpp]
* [issue 918] Calls to `<algorithm>` are protected from macros * ([issue 918]) Calls to `<algorithm>` are protected from macros
* [issue 954] The control callback is invoked on the proper executor * ([issue 954]) The control callback is invoked on the proper executor
* [issue 994] Fix iterator version of * ([issue 994]) Fix iterator version of
[link beast.ref.boost__beast__http__basic_fields.erase.overload1 `http::basic_fields::erase`] [link beast.ref.boost__beast__http__basic_fields.erase.overload1 `http::basic_fields::erase`]
* [issue 992] Fix use-after-move in example request handlers * ([issue 992]) Fix use-after-move in example request handlers
* [issue 988] Type check completion handlers * ([issue 988]) Type check completion handlers
* [issue 985] Tidy up * ([issue 985]) Tidy up
[link beast.ref.boost__beast__bind_handler `bind_handler`] [link beast.ref.boost__beast__bind_handler `bind_handler`]
doc doc
* Fix memory leak in advanced server examples * Fix memory leak in advanced server examples
* [issue 1000] Fix soft-mutex assert in websocket stream. * ([issue 1000]) Fix soft-mutex assert in websocket stream.
This resolves the assert `"ws_.wr_block_ == tok_"`. This resolves the assert `"ws_.wr_block_ == tok_"`.
* [issue 1019] Fix fallthrough warnings * ([issue 1019]) Fix fallthrough warnings
* [issue 1024] Fix teardown for TIME_WAIT * ([issue 1024]) Fix teardown for TIME_WAIT
* [issue 1030] Fix big-endian websocket masking * ([issue 1030]) Fix big-endian websocket masking
[*API Changes] [*API Changes]
@@ -126,19 +128,19 @@ to update to the latest Boost release.
constructor signature for state objects used with `handler_ptr` constructor signature for state objects used with `handler_ptr`
to receive a `const` reference to the handler. to receive a `const` reference to the handler.
* [issue 896] * ([issue 896])
[link beast.ref.boost__beast__http__basic_fields `http::basic_fields`] [link beast.ref.boost__beast__http__basic_fields `http::basic_fields`]
does not support fancy pointers does not support fancy pointers
* [link beast.ref.boost__beast__http__parser `http::parser`] * [link beast.ref.boost__beast__http__parser `http::parser`]
is no longer [*MoveConstructible] is no longer [*MoveConstructible]
* [issue 930] `http::serializer::reader_impl` is deprecated and will * ([issue 930]) `http::serializer::reader_impl` is deprecated and will
be removed in the next release. Actions required: Call be removed in the next release. Actions required: Call
[link beast.ref.boost__beast__http__serializer.writer_impl `http::serializer::writer_impl`] [link beast.ref.boost__beast__http__serializer.writer_impl `http::serializer::writer_impl`]
instead of `serializer::reader_impl`. instead of `serializer::reader_impl`.
* [issue 884] The __BodyReader__ and __BodyWriter__ concept constructor * ([issue 884]) The __BodyReader__ and __BodyWriter__ concept constructor
requirements have changed. They now require the header and body requirements have changed. They now require the header and body
elements to be passed as distinct elements to be passed as distinct
[link beast.ref.boost__beast__http__header `http::header`] [link beast.ref.boost__beast__http__header `http::header`]

View File

@@ -23,6 +23,7 @@
#include <boost/beast/version.hpp> #include <boost/beast/version.hpp>
#include <boost/asio/bind_executor.hpp> #include <boost/asio/bind_executor.hpp>
#include <boost/asio/ip/tcp.hpp> #include <boost/asio/ip/tcp.hpp>
#include <boost/asio/signal_set.hpp>
#include <boost/asio/ssl/stream.hpp> #include <boost/asio/ssl/stream.hpp>
#include <boost/asio/strand.hpp> #include <boost/asio/strand.hpp>
#include <boost/asio/steady_timer.hpp> #include <boost/asio/steady_timer.hpp>
@@ -1272,6 +1273,17 @@ int main(int argc, char* argv[])
tcp::endpoint{address, port}, tcp::endpoint{address, port},
doc_root)->run(); doc_root)->run();
// Capture SIGINT and SIGTERM to perform a clean shutdown
boost::asio::signal_set signals(ioc, SIGINT, SIGTERM);
signals.async_wait(
[&](boost::system::error_code const&, int)
{
// Stop the `io_context`. This will cause `run()`
// to return immediately, eventually destroying the
// `io_context` and all of the sockets in it.
ioc.stop();
});
// Run the I/O service on the requested number of threads // Run the I/O service on the requested number of threads
std::vector<std::thread> v; std::vector<std::thread> v;
v.reserve(threads - 1); v.reserve(threads - 1);
@@ -1283,5 +1295,11 @@ int main(int argc, char* argv[])
}); });
ioc.run(); ioc.run();
// (If we get here, it means we got a SIGINT or SIGTERM)
// Block until all the threads exit
for(auto& t : v)
t.join();
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View File

@@ -19,6 +19,7 @@
#include <boost/beast/version.hpp> #include <boost/beast/version.hpp>
#include <boost/asio/bind_executor.hpp> #include <boost/asio/bind_executor.hpp>
#include <boost/asio/ip/tcp.hpp> #include <boost/asio/ip/tcp.hpp>
#include <boost/asio/signal_set.hpp>
#include <boost/asio/strand.hpp> #include <boost/asio/strand.hpp>
#include <boost/asio/steady_timer.hpp> #include <boost/asio/steady_timer.hpp>
#include <boost/make_unique.hpp> #include <boost/make_unique.hpp>
@@ -815,6 +816,17 @@ int main(int argc, char* argv[])
tcp::endpoint{address, port}, tcp::endpoint{address, port},
doc_root)->run(); doc_root)->run();
// Capture SIGINT and SIGTERM to perform a clean shutdown
boost::asio::signal_set signals(ioc, SIGINT, SIGTERM);
signals.async_wait(
[&](boost::system::error_code const&, int)
{
// Stop the `io_context`. This will cause `run()`
// to return immediately, eventually destroying the
// `io_context` and all of the sockets in it.
ioc.stop();
});
// Run the I/O service on the requested number of threads // Run the I/O service on the requested number of threads
std::vector<std::thread> v; std::vector<std::thread> v;
v.reserve(threads - 1); v.reserve(threads - 1);
@@ -826,5 +838,11 @@ int main(int argc, char* argv[])
}); });
ioc.run(); ioc.run();
// (If we get here, it means we got a SIGINT or SIGTERM)
// Block until all the threads exit
for(auto& t : v)
t.join();
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }