RESTinio
http_server_run.hpp
Go to the documentation of this file.
1 /*
2  * restinio
3  */
4 
10 #pragma once
11 
13 
14 #include <restinio/http_server.hpp>
15 
16 namespace restinio
17 {
18 
19 //
20 // break_signal_handling_t
21 //
29 {
31  used,
33  skipped
34 };
35 
49 inline constexpr break_signal_handling_t
51 {
52  return break_signal_handling_t::used;
53 }
54 
68 inline constexpr break_signal_handling_t
70 {
72 }
73 
74 //
75 // run_on_this_thread_settings_t
76 //
85 template<typename Traits>
87  : public basic_server_settings_t<
88  run_on_this_thread_settings_t<Traits>,
89  Traits>
90 {
93 public:
94  // Inherit constructors from base class.
96 };
97 
98 //
99 // on_this_thread
100 //
121 template<typename Traits = default_single_thread_traits_t>
124 
125 //
126 // run_on_thread_pool_settings_t
127 //
136 template<typename Traits>
138  : public basic_server_settings_t<
139  run_on_thread_pool_settings_t<Traits>,
140  Traits>
141 {
143  std::size_t m_pool_size;
144 
145 public:
149  std::size_t pool_size )
151  {}
152 
154  std::size_t
155  pool_size() const { return m_pool_size; }
156 };
157 
158 //
159 // on_thread_pool
160 //
181 template<typename Traits = default_traits_t>
182 run_on_thread_pool_settings_t<Traits>
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 
214 template<typename Traits>
215 inline void
219  asio_ns::io_context & ioctx,
222 {
223  using settings_t = run_on_this_thread_settings_t<Traits>;
224  using server_t = http_server_t<Traits>;
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.
245  exception_caught = ex;
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();
257  exception_caught = ex;
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 
281 template<typename Traits>
282 inline void
285 {
286  asio_ns::io_context io_context;
287  run( io_context, std::move(settings) );
288 }
289 
290 namespace impl {
291 
301 template<typename Io_Context_Holder, typename Traits>
302 void
306 {
307  using settings_t = run_on_thread_pool_settings_t<Traits>;
308  using server_t = http_server_t<Traits>;
309 
310  server_t server{
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.
329  exception_caught = ex;
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();
341  exception_caught = ex;
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 
368 template<typename Traits>
369 inline void
371 {
372  using thread_pool_t = impl::ioctx_on_thread_pool_t<
374 
375  thread_pool_t pool( settings.pool_size() );
376 
377  impl::run( pool, std::move(settings) );
378 }
379 
381 
399 template<typename Traits>
400 inline void
404  asio_ns::io_context & ioctx,
407 {
408  using thread_pool_t = impl::ioctx_on_thread_pool_t<
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 //
428 template<typename Traits>
430 {
432  std::size_t m_pool_size;
436 
440 
441 public:
445  std::size_t pool_size,
454  , m_server{ &server }
455  {}
456 
457  std::size_t
458  pool_size() const noexcept { return m_pool_size; }
459 
461  break_handling() const noexcept { return m_break_handling; }
462 
464  server() const noexcept { return *m_server; }
465 };
466 
492 template<typename Traits>
493 run_existing_server_on_thread_pool_t<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 
502 namespace impl {
503 
518 template<typename Io_Context_Holder, typename Traits>
519 void
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.
539  exception_caught = ex;
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();
551  exception_caught = ex;
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 
575 template<typename Io_Context_Holder, typename Traits>
576 void
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();
590  exception_caught = ex;
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 
630 template<typename Traits>
631 inline void
633 {
634  using thread_pool_t = impl::ioctx_on_thread_pool_t<
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
642  impl::run_without_break_signal_handling( pool, params.server() );
643 }
644 
645 //
646 // initiate_shutdown
647 //
679 template<typename Traits>
680 inline void
682 {
683  server.io_context().post( [&server] {
684  server.close_sync();
685  server.io_context().stop();
686  } );
687 }
688 
689 //
690 // on_pool_runner_t
691 //
745 template<typename Http_Server>
747 {
749  Http_Server & m_server;
750 
754 
755 public :
756  on_pool_runner_t( const on_pool_runner_t & ) = delete;
758 
762  std::size_t pool_size,
766  Http_Server & server )
767  : m_server{ server }
768  , m_pool{ pool_size, server.io_context() }
769  {}
770 
817  template<
818  typename On_Ok_Callback,
819  typename On_Error_Callback >
820  void
823  On_Ok_Callback && on_ok,
831  On_Error_Callback && on_error )
832  {
833  static_assert( noexcept(on_ok()), "On_Ok_Callback should be noexcept" );
834  static_assert( noexcept(on_error(std::declval<std::exception_ptr>())),
835  "On_Error_Callback should be noexcept" );
836 
837  m_server.open_async(
838  [callback = std::move(on_ok)]{ callback(); },
839  [this, callback = std::move(on_error)]( std::exception_ptr ex ){
840  // There is no sense to run pool.
841  m_pool.stop();
842 
843  callback( std::move(ex) );
844  } );
845 
846  m_pool.start();
847  }
848 
850 
854  void
856  {
857  this->start(
858  []() noexcept { /* nothing to do */ },
859  []( std::exception_ptr ) noexcept { /* nothing to do */ } );
860  }
861 
863  bool
864  started() const noexcept { return m_pool.started(); }
865 
866  //FIXME: there should be a version of stop() with callbacks like
867  //for start() method above.
869 
873  void
874  stop() noexcept
875  {
876  m_server.close_async(
877  [this]{
878  // Stop running io_service.
879  m_pool.stop();
880  },
881  []( std::exception_ptr /*ex*/ ){
882  //FIXME: the exception should be stored to be handled
883  //later in wait() method.
884  //NOTE: this fix is planned for v.0.7.0.
885  //std::rethrow_exception( ex );
886  } );
887  }
888 
889  //FIXME this method should be replaced by two new method in v.0.7.0:
890  //
891  // enum class action_on_exception_t { drop, rethrow };
892  // wait(action_on_exception_t action);
893  //
894  // template<typename Exception_Handler>
895  // wait(Exception_Handler && on_exception);
896  //
898 
902  void
903  wait() noexcept { m_pool.wait(); }
904 };
905 
906 // Forward declaration.
907 // It's necessary for running_server_handle_t.
908 template< typename Http_Server >
909 class running_server_instance_t;
910 
911 //
912 // running_server_handle_t
913 //
921 template< typename Traits >
923  std::unique_ptr< running_server_instance_t< http_server_t<Traits> > >;
924 
925 //
926 // running_server_instance_t
927 //
940 template< typename Http_Server >
942 {
943  template< typename Traits >
945  run_async(
948  std::size_t thread_pool_size );
949 
951  Http_Server m_server;
952 
955 
958  io_context_holder_t io_context,
960  std::size_t thread_pool_size )
961  : m_server{ std::move(io_context), std::move(settings) }
962  , m_runner{ thread_pool_size, m_server }
963  {}
964 
965 
967 
974  void
976  {
977  std::promise<void> p;
978  auto f = p.get_future();
979  m_runner.start(
980  [&p]() noexcept { p.set_value(); },
981  [&p]( std::exception_ptr ex ) noexcept {
982  p.set_exception( std::move(ex) );
983  } );
984  f.get();
985  }
986 
987 public :
1008  void
1009  stop() noexcept
1010  {
1011  m_runner.stop();
1012  }
1013 
1031  void
1032  wait() noexcept
1033  {
1034  m_runner.wait();
1035  }
1036 };
1037 
1038 //
1039 // run_async
1040 //
1109 template< typename Traits = default_traits_t >
1111 running_server_handle_t< Traits >
1113  io_context_holder_t io_context,
1114  server_settings_t< Traits > && settings,
1115  std::size_t thread_pool_size )
1116 {
1119  std::move(io_context),
1120  std::move(settings),
1121  thread_pool_size }
1122  };
1123 
1124  handle->start();
1125 
1126  return handle;
1127 }
1128 
1129 } /* namespace restinio */
1130 
RESTINIO_NODISCARD
#define RESTINIO_NODISCARD
Definition: compiler_features.hpp:33
restinio::http_server_t
Class for http-server.
Definition: http_server.hpp:169
restinio::http_server_t::io_context
asio_ns::io_context & io_context() noexcept
Get io_context on which server runs.
Definition: http_server.hpp:249
restinio::running_server_instance_t::stop
void stop() noexcept
Definition: http_server_run.hpp:1009
restinio::http_server_t::open_async
void open_async(Server_Open_Ok_CB open_ok_cb, Server_Open_Error_CB open_err_cb)
Starts server in async way.
Definition: http_server.hpp:265
nonstd::optional_lite::std11::move
T & move(T &t)
Definition: optional.hpp:421
restinio::running_server_instance_t::wait
void wait() noexcept
Wait for the shutdown of HTTP-server.
Definition: http_server_run.hpp:1032
restinio::impl::external_io_context_for_thread_pool_t::io_context
auto & io_context() noexcept
Get access to io_context object.
Definition: ioctx_on_thread_pool.hpp:59
ioctx_on_thread_pool.hpp
restinio::io_context_holder_t
Helper class for holding shared pointer to io_context.
Definition: http_server.hpp:36
restinio::http_server_t::close_sync
void close_sync()
Stop server.
Definition: http_server.hpp:348
restinio::impl::own_io_context_for_thread_pool_t
A class for holding actual instance of Asio's io_context.
Definition: ioctx_on_thread_pool.hpp:26
restinio::run_existing_server_on_thread_pool_t::run_existing_server_on_thread_pool_t
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.
Definition: http_server_run.hpp:443
restinio::running_server_instance_t::m_server
Http_Server m_server
Actual server instance.
Definition: http_server_run.hpp:951
restinio::initiate_shutdown
void initiate_shutdown(http_server_t< Traits > &server)
Helper function for initiation of server shutdown.
Definition: http_server_run.hpp:681
restinio::impl::run_with_break_signal_handling
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.
Definition: http_server_run.hpp:520
restinio::on_pool_runner_t::m_server
Http_Server & m_server
HTTP-server to be run.
Definition: http_server_run.hpp:749
restinio::run_existing_server_on_thread_pool_t::m_pool_size
std::size_t m_pool_size
Size of thread pool.
Definition: http_server_run.hpp:432
restinio::on_pool_runner_t::on_pool_runner_t
on_pool_runner_t(on_pool_runner_t &&)=delete
restinio::on_pool_runner_t::start
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.
Definition: http_server_run.hpp:821
restinio::impl::external_io_context_for_thread_pool_t
A class for holding a reference to external Asio's io_context.
Definition: ioctx_on_thread_pool.hpp:47
restinio::run_existing_server_on_thread_pool_t::server
http_server_t< Traits > & server() const noexcept
Definition: http_server_run.hpp:464
restinio::on_pool_runner_t::wait
void wait() noexcept
Wait for full stop of the server.
Definition: http_server_run.hpp:903
restinio::impl::ioctx_on_thread_pool_t
Definition: ioctx_on_thread_pool.hpp:74
restinio::impl::ioctx_on_thread_pool_t::stop
void stop() noexcept
Definition: ioctx_on_thread_pool.hpp:146
restinio::running_server_handle_t
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.
Definition: http_server_run.hpp:923
restinio::on_pool_runner_t::stop
void stop() noexcept
Stop the server.
Definition: http_server_run.hpp:874
restinio::http_server_t::close_async
void close_async(Server_Close_Ok_CB close_ok_cb, Server_Close_Error_CB close_err_cb)
Closes server in async way.
Definition: http_server.hpp:319
restinio::impl::ioctx_on_thread_pool_t::io_context
asio_ns::io_context & io_context() noexcept
Definition: ioctx_on_thread_pool.hpp:174
restinio::on_pool_runner_t
Helper class for running an existing HTTP-server on a thread pool without blocking the current thread...
Definition: http_server_run.hpp:747
restinio::run_existing_server_on_thread_pool_t
Helper type for holding parameters necessary for running HTTP-server on a thread pool.
Definition: http_server_run.hpp:430
restinio::run_existing_server_on_thread_pool_t::m_break_handling
break_signal_handling_t m_break_handling
Should break signal handler be used?
Definition: http_server_run.hpp:434
restinio::break_signal_handling_t::used
@ used
Signal handler should be used by run() function.
restinio::on_this_thread
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.
Definition: http_server_run.hpp:123
restinio::on_pool_runner_t::on_pool_runner_t
on_pool_runner_t(std::size_t pool_size, Http_Server &server)
Initializing constructor.
Definition: http_server_run.hpp:760
restinio::running_server_instance_t::run_async
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.
Definition: http_server_run.hpp:1112
restinio::on_pool_runner_t::on_pool_runner_t
on_pool_runner_t(const on_pool_runner_t &)=delete
restinio::run_on_this_thread_settings_t
Settings for the case when http_server must be run on the context of the current thread.
Definition: http_server_run.hpp:90
restinio::impl::ioctx_on_thread_pool_t::start
void start()
Definition: ioctx_on_thread_pool.hpp:103
http_server.hpp
restinio::run_existing_server_on_thread_pool_t::break_handling
break_signal_handling_t break_handling() const noexcept
Definition: http_server_run.hpp:461
restinio::on_pool_runner_t::m_pool
impl::ioctx_on_thread_pool_t< impl::external_io_context_for_thread_pool_t > m_pool
Thread pool for running the server.
Definition: http_server_run.hpp:753
restinio::run
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.
Definition: http_server_run.hpp:216
restinio::run_existing_server_on_thread_pool_t::pool_size
std::size_t pool_size() const noexcept
Definition: http_server_run.hpp:458
restinio::running_server_instance_t::running_server_instance_t
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.
Definition: http_server_run.hpp:957
restinio::running_server_instance_t
A helper class used in an implementation of run_async function.
Definition: http_server_run.hpp:942
restinio::impl::run_without_break_signal_handling
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.
Definition: http_server_run.hpp:577
restinio::running_server_instance_t::start
void start()
Start the HTTP-server.
Definition: http_server_run.hpp:975
restinio::skip_break_signal_handling
constexpr break_signal_handling_t skip_break_signal_handling() noexcept
Make the indicator for absence of break signal handler.
Definition: http_server_run.hpp:69
restinio::on_thread_pool
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.
Definition: http_server_run.hpp:183
restinio
Definition: asio_include.hpp:21
restinio::basic_server_settings_t< run_on_this_thread_settings_t< Traits >, Traits >::base_type_t
socket_type_dependent_settings_t< run_on_this_thread_settings_t< Traits >, typename Traits::stream_socket_t > base_type_t
Definition: settings.hpp:558
restinio::run_on_thread_pool_settings_t::pool_size
std::size_t pool_size() const
Get the pool size.
Definition: http_server_run.hpp:155
restinio::impl::ioctx_on_thread_pool_t::wait
void wait() noexcept
Definition: ioctx_on_thread_pool.hpp:159
restinio::use_break_signal_handling
constexpr break_signal_handling_t use_break_signal_handling() noexcept
Make the indicator for usage of break signal handler.
Definition: http_server_run.hpp:50
restinio::impl::run
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.
Definition: http_server_run.hpp:303
restinio::basic_server_settings_t
Basic container for http_server settings.
Definition: settings.hpp:556
restinio::run_on_thread_pool_settings_t::run_on_thread_pool_settings_t
run_on_thread_pool_settings_t(std::size_t pool_size)
Constructor.
Definition: http_server_run.hpp:147
restinio::external_io_context
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...
Definition: http_server.hpp:87
restinio::run_on_thread_pool_settings_t
Settings for the case when http_server must be run on the context of the current thread.
Definition: http_server_run.hpp:141
restinio::break_signal_handling_t
break_signal_handling_t
Indication of usage of break signal handlers for some forms of run functions.
Definition: http_server_run.hpp:29
restinio::run_async
RESTINIO_NODISCARD 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.
Definition: http_server_run.hpp:1112
restinio::server_settings_t
A fluent style interface for setting http server params.
Definition: settings.hpp:1650
restinio::run_on_thread_pool_settings_t::m_pool_size
std::size_t m_pool_size
Size of the pool.
Definition: http_server_run.hpp:143
restinio::run_existing_server_on_thread_pool_t::m_server
http_server_t< Traits > * m_server
HTTP-server to be used on a thread pool.
Definition: http_server_run.hpp:439
restinio::running_server_instance_t::m_runner
on_pool_runner_t< Http_Server > m_runner
The runner of the server.
Definition: http_server_run.hpp:954
restinio::on_pool_runner_t::start
void start()
Start the server.
Definition: http_server_run.hpp:855
const
#define const
Definition: zconf.h:230
restinio::on_pool_runner_t::started
bool started() const noexcept
Is server started.
Definition: http_server_run.hpp:864