RESTinio
Loading...
Searching...
No Matches
http_server_run.hpp
Go to the documentation of this file.
1/*
2 * restinio
3 */
4
10#pragma once
11
13
15
16namespace restinio
17{
18
19//
20// break_signal_handling_t
21//
29{
31 used,
34};
35
49inline constexpr break_signal_handling_t
54
68inline constexpr break_signal_handling_t
73
74//
75// run_on_this_thread_settings_t
76//
85template<typename Traits>
88 run_on_this_thread_settings_t<Traits>,
89 Traits>
90{
93public:
94 // Inherit constructors from base class.
96};
97
98//
99// on_this_thread
100//
121template<typename Traits = default_single_thread_traits_t>
124
125//
126// run_on_thread_pool_settings_t
127//
136template<typename Traits>
139 run_on_thread_pool_settings_t<Traits>,
140 Traits>
141{
143 std::size_t m_pool_size;
144
145public:
152
154 std::size_t
155 pool_size() const { return m_pool_size; }
156};
157
158//
159// on_thread_pool
160//
181template<typename Traits = default_traits_t>
185 std::size_t pool_size )
186{
187 return run_on_thread_pool_settings_t<Traits>( pool_size );
188}
189
190//
191// run()
192//
193
194
196
214template<typename Traits>
215inline void
219 asio_ns::io_context & ioctx,
222{
225
226 server_t server{
228 std::forward<settings_t>(settings) };
229
230 std::exception_ptr exception_caught;
231
232 asio_ns::signal_set break_signals{ server.io_context(), SIGINT };
233 break_signals.async_wait(
234 [&]( const asio_ns::error_code & ec, int ){
235 if( !ec )
236 {
237 server.close_async(
238 [&]{
239 // Stop running io_service.
240 ioctx.stop();
241 },
242 [&exception_caught]( std::exception_ptr ex ){
243 // We can't throw an exception here!
244 // Store it to rethrow later.
246 } );
247 }
248 } );
249
250 server.open_async(
251 []{ /* Ok. */},
252 [&ioctx, &exception_caught]( std::exception_ptr ex ){
253 // Stop running io_service.
254 // We can't throw an exception here!
255 // Store it to rethrow later.
256 ioctx.stop();
258 } );
259
260 ioctx.run();
261
262 // If an error was detected it should be propagated.
263 if( exception_caught )
264 std::rethrow_exception( exception_caught );
265}
266
268
281template<typename Traits>
282inline void
285{
286 asio_ns::io_context io_context;
287 run( io_context, std::move(settings) );
288}
289
290namespace impl {
291
301template<typename Io_Context_Holder, typename Traits>
302void
306{
309
310 server_t server{
311 restinio::external_io_context( pool.io_context() ),
312 std::forward<settings_t>(settings) };
313
314 std::exception_ptr exception_caught;
315
316 asio_ns::signal_set break_signals{ server.io_context(), SIGINT };
317 break_signals.async_wait(
318 [&]( const asio_ns::error_code & ec, int ){
319 if( !ec )
320 {
321 server.close_async(
322 [&]{
323 // Stop running io_service.
324 pool.stop();
325 },
326 [&exception_caught]( std::exception_ptr ex ){
327 // We can't throw an exception here!
328 // Store it to rethrow later.
330 } );
331 }
332 } );
333
334 server.open_async(
335 []{ /* Ok. */},
336 [&pool, &exception_caught]( std::exception_ptr ex ){
337 // Stop running io_service.
338 // We can't throw an exception here!
339 // Store it to rethrow later.
340 pool.stop();
342 } );
343
344 pool.start();
345 pool.wait();
346
347 // If an error was detected it should be propagated.
348 if( exception_caught )
349 std::rethrow_exception( exception_caught );
350}
351
352} /* namespace impl */
353
355
368template<typename Traits>
369inline void
379
381
399template<typename Traits>
400inline void
404 asio_ns::io_context & ioctx,
407{
410
411 thread_pool_t pool{ settings.pool_size(), ioctx };
412
413 impl::run( pool, std::move(settings) );
414}
415
416//
417// run_existing_server_on_thread_pool_t
418//
428template<typename Traits>
466
492template<typename Traits>
495 std::size_t pool_size,
496 break_signal_handling_t break_handling,
497 http_server_t<Traits> & server )
498{
499 return { pool_size, break_handling, server };
500}
501
502namespace impl {
503
518template<typename Io_Context_Holder, typename Traits>
519void
522 http_server_t<Traits> & server )
523{
524 std::exception_ptr exception_caught;
525
526 asio_ns::signal_set break_signals{ server.io_context(), SIGINT };
527 break_signals.async_wait(
528 [&]( const asio_ns::error_code & ec, int ){
529 if( !ec )
530 {
531 server.close_async(
532 [&]{
533 // Stop running io_service.
534 pool.stop();
535 },
536 [&exception_caught]( std::exception_ptr ex ){
537 // We can't throw an exception here!
538 // Store it to rethrow later.
540 } );
541 }
542 } );
543
544 server.open_async(
545 []{ /* Ok. */},
546 [&pool, &exception_caught]( std::exception_ptr ex ){
547 // Stop running io_service.
548 // We can't throw an exception here!
549 // Store it to rethrow later.
550 pool.stop();
552 } );
553
554 pool.start();
555 pool.wait();
556
557 // If an error was detected it should be propagated.
558 if( exception_caught )
559 std::rethrow_exception( exception_caught );
560}
561
575template<typename Io_Context_Holder, typename Traits>
576void
579 http_server_t<Traits> & server )
580{
581 std::exception_ptr exception_caught;
582
583 server.open_async(
584 []{ /* Ok. */},
585 [&pool, &exception_caught]( std::exception_ptr ex ){
586 // Stop running io_service.
587 // We can't throw an exception here!
588 // Store it to rethrow later.
589 pool.stop();
591 } );
592
593 pool.start();
594 pool.wait();
595
596 // If an error was detected it should be propagated.
597 if( exception_caught )
598 std::rethrow_exception( exception_caught );
599}
600
601} /* namespace impl */
602
630template<typename Traits>
631inline void
633{
636
637 thread_pool_t pool{ params.pool_size(), params.server().io_context() };
638
639 if( break_signal_handling_t::used == params.break_handling() )
640 impl::run_with_break_signal_handling( pool, params.server() );
641 else
643}
644
645//
646// initiate_shutdown
647//
679template<typename Traits>
680inline void
682{
683 server.io_context().post( [&server] {
684 server.close_sync();
685 server.io_context().stop();
686 } );
687}
688
713{
718 [[noreturn]]
719 void
720 operator()( std::exception_ptr /*ex*/ ) const noexcept
721 {
722 std::abort();
723 }
724};
725
726//
727// on_pool_runner_t
728//
782template<typename Http_Server>
784{
787
791
792public :
795
799 std::size_t pool_size,
803 Http_Server & server )
804 : m_server{ server }
805 , m_pool{ pool_size, server.io_context() }
806 {}
807
854 template<
855 typename On_Ok_Callback,
856 typename On_Error_Callback >
857 void
869 {
870 static_assert( noexcept(on_ok()), "On_Ok_Callback should be noexcept" );
871 static_assert( noexcept(on_error(std::declval<std::exception_ptr>())),
872 "On_Error_Callback should be noexcept" );
873
874 m_server.open_async(
875 [callback = std::move(on_ok)]() noexcept { callback(); },
876 [this, callback = std::move(on_error)]( std::exception_ptr ex ) noexcept {
877 // There is no sense to run pool.
878 m_pool.stop();
879
880 callback( std::move(ex) );
881 } );
882
883 m_pool.start();
884 }
885
887
891 void
893 {
894 this->start(
895 []() noexcept { /* nothing to do */ },
896 []( std::exception_ptr ) noexcept { /* nothing to do */ } );
897 }
898
900 bool
901 started() const noexcept { return m_pool.started(); }
902
904
963 template< typename Error_CB = abort_app_in_error_callback_t >
964 void
966 {
967 // NOTE: m_pool.stop() call be called only inside lambda-functions
968 // because they may be executed some time later after the return
969 // from close_async().
970 m_server.close_async(
971 [this]() noexcept {
972 // Stop running io_service.
973 m_pool.stop();
974 },
975 [this, callback = std::move(error_cb)]( std::exception_ptr ex ) noexcept {
976 // Stop running io_service anyway.
977 m_pool.stop();
978
979 // We have to call error_cb in this case.
980 callback( std::move(ex) );
981 } );
982 }
983
985
989 void
990 wait() noexcept { m_pool.wait(); }
991};
992
993// Forward declaration.
994// It's necessary for running_server_handle_t.
995template< typename Http_Server >
996class running_server_instance_t;
997
998//
999// running_server_handle_t
1000//
1008template< typename Traits >
1010 std::unique_ptr< running_server_instance_t< http_server_t<Traits> > >;
1011
1012//
1013// running_server_instance_t
1014//
1027template< typename Http_Server >
1029{
1030 template< typename Traits >
1032 run_async(
1035 std::size_t thread_pool_size );
1036
1039
1042
1051
1052
1054
1061 void
1063 {
1064 std::promise<void> p;
1065 auto f = p.get_future();
1066 m_runner.start(
1067 [&p]() noexcept { p.set_value(); },
1068 [&p]( std::exception_ptr ex ) noexcept {
1069 p.set_exception( std::move(ex) );
1070 } );
1071 f.get();
1072 }
1073
1074public :
1095 void
1097 {
1098 m_runner.stop();
1099 }
1100
1118 void
1120 {
1121 m_runner.wait();
1122 }
1123};
1124
1125//
1126// run_async
1127//
1196template< typename Traits = default_traits_t >
1197[[nodiscard]]
1200 io_context_holder_t io_context,
1202 std::size_t thread_pool_size )
1203{
1206 std::move(io_context),
1207 std::move(settings),
1209 };
1210
1211 handle->start();
1212
1213 return handle;
1214}
1215
1216} /* namespace restinio */
1217
Basic container for http_server settings.
Definition settings.hpp:555
Class for http-server.
void close_sync()
Stop server.
void open_async(Server_Open_Ok_CB open_ok_cb, Server_Open_Error_CB open_err_cb)
Starts server in async way.
void close_async(Server_Close_Ok_CB close_ok_cb, Server_Close_Error_CB close_err_cb)
Closes server in async way.
asio_ns::io_context & io_context() noexcept
Get io_context on which server runs.
A class for holding a reference to external Asio's io_context.
auto & io_context() noexcept
Get access to io_context object.
A class for holding actual instance of Asio's io_context.
Helper class for holding shared pointer to io_context.
Helper class for running an existing HTTP-server on a thread pool without blocking the current thread...
void wait() noexcept
Wait for full stop of the server.
void start()
Start the server.
on_pool_runner_t(std::size_t pool_size, Http_Server &server)
Initializing constructor.
impl::ioctx_on_thread_pool_t< impl::external_io_context_for_thread_pool_t > m_pool
Thread pool for running the server.
on_pool_runner_t(const on_pool_runner_t &)=delete
bool started() const noexcept
Is server started.
void start(On_Ok_Callback &&on_ok, On_Error_Callback &&on_error)
Start the server with callbacks that will be called on success or failure.
void stop(Error_CB error_cb=Error_CB{}) noexcept
Stop the server.
on_pool_runner_t(on_pool_runner_t &&)=delete
Http_Server & m_server
HTTP-server to be run.
Helper type for holding parameters necessary for running HTTP-server on a thread pool.
http_server_t< Traits > * m_server
HTTP-server to be used on a thread pool.
break_signal_handling_t m_break_handling
Should break signal handler be used?
break_signal_handling_t break_handling() const noexcept
run_existing_server_on_thread_pool_t(std::size_t pool_size, break_signal_handling_t break_handling, http_server_t< Traits > &server)
Initializing constructor.
http_server_t< Traits > & server() const noexcept
Settings for the case when http_server must be run on the context of the current thread.
Settings for the case when http_server must be run on the context of the current thread.
std::size_t m_pool_size
Size of the pool.
std::size_t pool_size() const
Get the pool size.
run_on_thread_pool_settings_t(std::size_t pool_size)
Constructor.
A helper class used in an implementation of run_async function.
void start()
Start the HTTP-server.
void wait() noexcept
Wait for the shutdown of HTTP-server.
Http_Server m_server
Actual server instance.
running_server_instance_t(io_context_holder_t io_context, server_settings_t< typename Http_Server::traits_t > &&settings, std::size_t thread_pool_size)
Initializing constructor.
on_pool_runner_t< Http_Server > m_runner
The runner of the server.
friend running_server_handle_t< Traits > run_async(io_context_holder_t, server_settings_t< Traits > &&, std::size_t thread_pool_size)
Creates an instance of HTTP-server and launches it on a separate thread or thread pool.
A fluent style interface for setting http server params.
Extra settings needed for working with socket.
Definition settings.hpp:154
void run_without_break_signal_handling(ioctx_on_thread_pool_t< Io_Context_Holder > &pool, http_server_t< Traits > &server)
An implementation of run-function for thread pool case with existing http_server instance.
void run(ioctx_on_thread_pool_t< Io_Context_Holder > &pool, run_on_thread_pool_settings_t< Traits > &&settings)
An implementation of run-function for thread pool case.
void run_with_break_signal_handling(ioctx_on_thread_pool_t< Io_Context_Holder > &pool, http_server_t< Traits > &server)
An implementation of run-function for thread pool case with existing http_server instance.
constexpr break_signal_handling_t skip_break_signal_handling() noexcept
Make the indicator for absence of break signal handler.
run_on_thread_pool_settings_t< Traits > on_thread_pool(std::size_t pool_size)
A special marker for the case when http_server must be run on an thread pool.
run_on_this_thread_settings_t< Traits > on_this_thread()
A special marker for the case when http_server must be run on the context of the current thread.
io_context_holder_t external_io_context(asio_ns::io_context &ctx)
Function which tells that http_server should use external instance of io_context and should not contr...
running_server_handle_t< Traits > run_async(io_context_holder_t io_context, server_settings_t< Traits > &&settings, std::size_t thread_pool_size)
Creates an instance of HTTP-server and launches it on a separate thread or thread pool.
std::unique_ptr< running_server_instance_t< http_server_t< Traits > > > running_server_handle_t
The type to be used as a handle for running server instance.
constexpr break_signal_handling_t use_break_signal_handling() noexcept
Make the indicator for usage of break signal handler.
void run(asio_ns::io_context &ioctx, run_on_this_thread_settings_t< Traits > &&settings)
Helper function for running http server until ctrl+c is hit.
break_signal_handling_t
Indication of usage of break signal handlers for some forms of run functions.
@ used
Signal handler should be used by run() function.
@ skipped
Signal handler should not be used by run() function.
void initiate_shutdown(http_server_t< Traits > &server)
Helper function for initiation of server shutdown.
Type of a function to be used as the default on_error-callback.
void operator()(std::exception_ptr) const noexcept