http_server_run.hpp
Go to the documentation of this file.
/*
* restinio
*/
#pragma once
#include <restinio/impl/ioctx_on_thread_pool.hpp>
#include <restinio/http_server.hpp>
namespace restinio
{
//
// break_signal_handling_t
//
enum class break_signal_handling_t
{
used,
skipped
};
inline constexpr break_signal_handling_t
use_break_signal_handling() noexcept
{
return break_signal_handling_t::used;
}
inline constexpr break_signal_handling_t
skip_break_signal_handling() noexcept
{
return break_signal_handling_t::skipped;
}
//
// run_on_this_thread_settings_t
//
template<typename Traits>
class run_on_this_thread_settings_t final
: public basic_server_settings_t<
run_on_this_thread_settings_t<Traits>,
Traits>
{
using base_type_t = basic_server_settings_t<
run_on_this_thread_settings_t<Traits>, Traits>;
public:
// Inherit constructors from base class.
using base_type_t::base_type_t;
};
//
// on_this_thread
//
template<typename Traits = default_single_thread_traits_t>
run_on_this_thread_settings_t<Traits>
on_this_thread() { return run_on_this_thread_settings_t<Traits>{}; }
//
// run_on_thread_pool_settings_t
//
template<typename Traits>
class run_on_thread_pool_settings_t final
: public basic_server_settings_t<
run_on_thread_pool_settings_t<Traits>,
Traits>
{
std::size_t m_pool_size;
public:
run_on_thread_pool_settings_t(
std::size_t pool_size )
: m_pool_size(pool_size)
{}
std::size_t
pool_size() const { return m_pool_size; }
};
//
// on_thread_pool
//
template<typename Traits = default_traits_t>
run_on_thread_pool_settings_t<Traits>
on_thread_pool(
std::size_t pool_size )
{
return run_on_thread_pool_settings_t<Traits>( pool_size );
}
//
// run()
//
template<typename Traits>
inline void
run(
asio_ns::io_context & ioctx,
run_on_this_thread_settings_t<Traits> && settings )
{
using settings_t = run_on_this_thread_settings_t<Traits>;
using server_t = http_server_t<Traits>;
server_t server{
restinio::external_io_context( ioctx ),
std::forward<settings_t>(settings) };
std::exception_ptr exception_caught;
asio_ns::signal_set break_signals{ server.io_context(), SIGINT };
break_signals.async_wait(
[&]( const asio_ns::error_code & ec, int ){
if( !ec )
{
server.close_async(
[&]{
// Stop running io_service.
ioctx.stop();
},
[&exception_caught]( std::exception_ptr ex ){
// We can't throw an exception here!
// Store it to rethrow later.
exception_caught = ex;
} );
}
} );
server.open_async(
[]{ /* Ok. */},
[&ioctx, &exception_caught]( std::exception_ptr ex ){
// Stop running io_service.
// We can't throw an exception here!
// Store it to rethrow later.
ioctx.stop();
exception_caught = ex;
} );
ioctx.run();
// If an error was detected it should be propagated.
if( exception_caught )
std::rethrow_exception( exception_caught );
}
template<typename Traits>
inline void
run(
run_on_this_thread_settings_t<Traits> && settings )
{
asio_ns::io_context io_context;
run( io_context, std::move(settings) );
}
namespace impl {
template<typename Io_Context_Holder, typename Traits>
void
run(
ioctx_on_thread_pool_t<Io_Context_Holder> & pool,
run_on_thread_pool_settings_t<Traits> && settings )
{
using settings_t = run_on_thread_pool_settings_t<Traits>;
using server_t = http_server_t<Traits>;
server_t server{
restinio::external_io_context( pool.io_context() ),
std::forward<settings_t>(settings) };
std::exception_ptr exception_caught;
asio_ns::signal_set break_signals{ server.io_context(), SIGINT };
break_signals.async_wait(
[&]( const asio_ns::error_code & ec, int ){
if( !ec )
{
server.close_async(
[&]{
// Stop running io_service.
pool.stop();
},
[&exception_caught]( std::exception_ptr ex ){
// We can't throw an exception here!
// Store it to rethrow later.
exception_caught = ex;
} );
}
} );
server.open_async(
[]{ /* Ok. */},
[&pool, &exception_caught]( std::exception_ptr ex ){
// Stop running io_service.
// We can't throw an exception here!
// Store it to rethrow later.
pool.stop();
exception_caught = ex;
} );
pool.start();
pool.wait();
// If an error was detected it should be propagated.
if( exception_caught )
std::rethrow_exception( exception_caught );
}
} /* namespace impl */
template<typename Traits>
inline void
run( run_on_thread_pool_settings_t<Traits> && settings )
{
using thread_pool_t = impl::ioctx_on_thread_pool_t<
impl::own_io_context_for_thread_pool_t >;
thread_pool_t pool( settings.pool_size() );
impl::run( pool, std::move(settings) );
}
template<typename Traits>
inline void
run(
asio_ns::io_context & ioctx,
run_on_thread_pool_settings_t<Traits> && settings )
{
using thread_pool_t = impl::ioctx_on_thread_pool_t<
impl::external_io_context_for_thread_pool_t >;
thread_pool_t pool{ settings.pool_size(), ioctx };
impl::run( pool, std::move(settings) );
}
//
// run_existing_server_on_thread_pool_t
//
template<typename Traits>
class run_existing_server_on_thread_pool_t
{
std::size_t m_pool_size;
break_signal_handling_t m_break_handling;
http_server_t<Traits> * m_server;
public:
run_existing_server_on_thread_pool_t(
std::size_t pool_size,
break_signal_handling_t break_handling,
http_server_t<Traits> & server )
: m_pool_size{ pool_size }
, m_break_handling{ break_handling }
, m_server{ &server }
{}
std::size_t
pool_size() const noexcept { return m_pool_size; }
break_signal_handling_t
break_handling() const noexcept { return m_break_handling; }
http_server_t<Traits> &
server() const noexcept { return *m_server; }
};
template<typename Traits>
run_existing_server_on_thread_pool_t<Traits>
on_thread_pool(
std::size_t pool_size,
break_signal_handling_t break_handling,
http_server_t<Traits> & server )
{
return { pool_size, break_handling, server };
}
namespace impl {
template<typename Io_Context_Holder, typename Traits>
void
run_with_break_signal_handling(
ioctx_on_thread_pool_t<Io_Context_Holder> & pool,
http_server_t<Traits> & server )
{
std::exception_ptr exception_caught;
asio_ns::signal_set break_signals{ server.io_context(), SIGINT };
break_signals.async_wait(
[&]( const asio_ns::error_code & ec, int ){
if( !ec )
{
server.close_async(
[&]{
// Stop running io_service.
pool.stop();
},
[&exception_caught]( std::exception_ptr ex ){
// We can't throw an exception here!
// Store it to rethrow later.
exception_caught = ex;
} );
}
} );
server.open_async(
[]{ /* Ok. */},
[&pool, &exception_caught]( std::exception_ptr ex ){
// Stop running io_service.
// We can't throw an exception here!
// Store it to rethrow later.
pool.stop();
exception_caught = ex;
} );
pool.start();
pool.wait();
// If an error was detected it should be propagated.
if( exception_caught )
std::rethrow_exception( exception_caught );
}
template<typename Io_Context_Holder, typename Traits>
void
run_without_break_signal_handling(
ioctx_on_thread_pool_t<Io_Context_Holder> & pool,
http_server_t<Traits> & server )
{
std::exception_ptr exception_caught;
server.open_async(
[]{ /* Ok. */},
[&pool, &exception_caught]( std::exception_ptr ex ){
// Stop running io_service.
// We can't throw an exception here!
// Store it to rethrow later.
pool.stop();
exception_caught = ex;
} );
pool.start();
pool.wait();
// If an error was detected it should be propagated.
if( exception_caught )
std::rethrow_exception( exception_caught );
}
} /* namespace impl */
template<typename Traits>
inline void
run( run_existing_server_on_thread_pool_t<Traits> && params )
{
using thread_pool_t = impl::ioctx_on_thread_pool_t<
impl::external_io_context_for_thread_pool_t >;
thread_pool_t pool{ params.pool_size(), params.server().io_context() };
if( break_signal_handling_t::used == params.break_handling() )
impl::run_with_break_signal_handling( pool, params.server() );
else
impl::run_without_break_signal_handling( pool, params.server() );
}
//
// initiate_shutdown
//
template<typename Traits>
inline void
initiate_shutdown( http_server_t<Traits> & server )
{
server.io_context().post( [&server] {
server.close_sync();
server.io_context().stop();
} );
}
//
// on_pool_runner_t
//
template<typename Http_Server>
class on_pool_runner_t
{
Http_Server & m_server;
impl::ioctx_on_thread_pool_t< impl::external_io_context_for_thread_pool_t >
m_pool;
public :
on_pool_runner_t( const on_pool_runner_t & ) = delete;
on_pool_runner_t( on_pool_runner_t && ) = delete;
on_pool_runner_t(
std::size_t pool_size,
Http_Server & server )
: m_server{ server }
, m_pool{ pool_size, server.io_context() }
{}
template<
typename On_Ok_Callback,
typename On_Error_Callback >
void
start(
On_Ok_Callback && on_ok,
On_Error_Callback && on_error )
{
static_assert( noexcept(on_ok()), "On_Ok_Callback should be noexcept" );
static_assert( noexcept(on_error(std::declval<std::exception_ptr>())),
"On_Error_Callback should be noexcept" );
m_server.open_async(
[callback = std::move(on_ok)]{ callback(); },
[this, callback = std::move(on_error)]( std::exception_ptr ex ){
// There is no sense to run pool.
m_pool.stop();
callback( std::move(ex) );
} );
m_pool.start();
}
void
start()
{
this->start(
[]() noexcept { /* nothing to do */ },
[]( std::exception_ptr ) noexcept { /* nothing to do */ } );
}
bool
started() const noexcept { return m_pool.started(); }
//FIXME: there should be a version of stop() with callbacks like
//for start() method above.
void
stop() noexcept
{
m_server.close_async(
[this]{
// Stop running io_service.
m_pool.stop();
},
[]( std::exception_ptr /*ex*/ ){
//FIXME: the exception should be stored to be handled
//later in wait() method.
//NOTE: this fix is planned for v.0.7.0.
//std::rethrow_exception( ex );
} );
}
//FIXME this method should be replaced by two new method in v.0.7.0:
//
// enum class action_on_exception_t { drop, rethrow };
// wait(action_on_exception_t action);
//
// template<typename Exception_Handler>
// wait(Exception_Handler && on_exception);
//
void
wait() noexcept { m_pool.wait(); }
};
// Forward declaration.
// It's necessary for running_server_handle_t.
template< typename Http_Server >
class running_server_instance_t;
//
// running_server_handle_t
//
template< typename Traits >
using running_server_handle_t =
std::unique_ptr< running_server_instance_t< http_server_t<Traits> > >;
//
// running_server_instance_t
//
template< typename Http_Server >
class running_server_instance_t
{
template< typename Traits >
friend running_server_handle_t<Traits>
run_async(
io_context_holder_t,
server_settings_t<Traits> &&,
std::size_t thread_pool_size );
Http_Server m_server;
on_pool_runner_t< Http_Server > m_runner;
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 )
: m_server{ std::move(io_context), std::move(settings) }
, m_runner{ thread_pool_size, m_server }
{}
void
start()
{
std::promise<void> p;
auto f = p.get_future();
m_runner.start(
[&p]() noexcept { p.set_value(); },
[&p]( std::exception_ptr ex ) noexcept {
p.set_exception( std::move(ex) );
} );
f.get();
}
public :
void
stop() noexcept
{
m_runner.stop();
}
void
wait() noexcept
{
m_runner.wait();
}
};
//
// run_async
//
template< typename Traits = default_traits_t >
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 )
{
running_server_handle_t< Traits > handle{
new running_server_instance_t< http_server_t<Traits> >{
std::move(io_context),
std::move(settings),
thread_pool_size }
};
handle->start();
return handle;
}
} /* namespace restinio */
restinio::basic_server_settings_t
Basic container for http_server settings.
Definition: settings.hpp:556
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::http_server_t< Traits >
restinio::http_server_t::close_sync
void close_sync()
Stop server.
Definition: http_server.hpp:348
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
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::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::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::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
restinio::impl::ioctx_on_thread_pool_t
Definition: ioctx_on_thread_pool.hpp:74
restinio::impl::ioctx_on_thread_pool_t::io_context
asio_ns::io_context & io_context() noexcept
Definition: ioctx_on_thread_pool.hpp:174
restinio::impl::ioctx_on_thread_pool_t::wait
void wait() noexcept
Definition: ioctx_on_thread_pool.hpp:159
restinio::impl::ioctx_on_thread_pool_t::stop
void stop() noexcept
Definition: ioctx_on_thread_pool.hpp:146
restinio::impl::ioctx_on_thread_pool_t::start
void start()
Definition: ioctx_on_thread_pool.hpp:103
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::io_context_holder_t
Helper class for holding shared pointer to io_context.
Definition: http_server.hpp:36
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::on_pool_runner_t::wait
void wait() noexcept
Wait for full stop of the server.
Definition: http_server_run.hpp:903
restinio::on_pool_runner_t::start
void start()
Start the server.
Definition: http_server_run.hpp:855
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::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::on_pool_runner_t::stop
void stop() noexcept
Stop the server.
Definition: http_server_run.hpp:874
restinio::on_pool_runner_t::on_pool_runner_t
on_pool_runner_t(const on_pool_runner_t &)=delete
restinio::on_pool_runner_t::started
bool started() const noexcept
Is server started.
Definition: http_server_run.hpp:864
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::on_pool_runner_t::on_pool_runner_t
on_pool_runner_t(on_pool_runner_t &&)=delete
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
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_server
http_server_t< Traits > * m_server
HTTP-server to be used on a thread pool.
Definition: http_server_run.hpp:439
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::run_existing_server_on_thread_pool_t::break_handling
break_signal_handling_t break_handling() const noexcept
Definition: http_server_run.hpp:461
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::run_existing_server_on_thread_pool_t::pool_size
std::size_t pool_size() const noexcept
Definition: http_server_run.hpp:458
restinio::run_existing_server_on_thread_pool_t::server
http_server_t< Traits > & server() const noexcept
Definition: http_server_run.hpp:464
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::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::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::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_on_thread_pool_settings_t::pool_size
std::size_t pool_size() const
Get the pool size.
Definition: http_server_run.hpp:155
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::running_server_instance_t
A helper class used in an implementation of run_async function.
Definition: http_server_run.hpp:942
restinio::running_server_instance_t::stop
void stop() noexcept
Definition: http_server_run.hpp:1009
restinio::running_server_instance_t::start
void start()
Start the HTTP-server.
Definition: http_server_run.hpp:975
restinio::running_server_instance_t::wait
void wait() noexcept
Wait for the shutdown of HTTP-server.
Definition: http_server_run.hpp:1032
restinio::running_server_instance_t::m_server
Http_Server m_server
Actual server instance.
Definition: http_server_run.hpp:951
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::m_runner
on_pool_runner_t< Http_Server > m_runner
The runner of the server.
Definition: http_server_run.hpp:954
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::server_settings_t
A fluent style interface for setting http server params.
Definition: settings.hpp:1768
RESTINIO_NODISCARD
#define RESTINIO_NODISCARD
Definition: compiler_features.hpp:33
http_server.hpp
ioctx_on_thread_pool.hpp
nonstd::optional_lite::std11::move
T & move(T &t)
Definition: optional.hpp:465
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::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::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
Definition: asio_include.hpp:21
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::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::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::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::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::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_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::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::break_signal_handling_t::used
@ used
Signal handler should be used by run() function.
restinio::break_signal_handling_t::skipped
@ skipped
Signal handler should not be used by run() function.
restinio::initiate_shutdown
void initiate_shutdown(http_server_t< Traits > &server)
Helper function for initiation of server shutdown.
Definition: http_server_run.hpp:681
std
STL namespace.
const
#define const
Definition: zconf.h:230