Traits
List of types that must be defined be Traits
timer_manager_t
defines the logic of how timeouts are managed;logger_t
defines logger that is used by RESTinio to track its inner logic;request_handler_t
defines a function-like type to be used as request handler;strand_t
- defines a class that is used by connection as a wrapper for its callback-handlers running onasio::io_context
thread(s) in order to guarantee serialized callbacks invocation (see asio doc). Actually, there are two options for the strand type:asio::strand<asio::executor>
andasio::executor
. The first is a real strand that guarantees serialized invocation and the second one is simply a default executor to eliminate unnecessary overhead when runningasio::io_context
on a single thread;stream_socket_t
is a customization point that tells restinio what type of socket used for connections. This parameter allows restinio to support TLS connection (see TLS support).
timer_manager_t
timer_manager_t
- defines a timeout controller logic.
It must define two nested types.
The first one is timer_guard_t
with the following interface:
class timer_guard_t
{
public:
// Schedule a checking of timed out operations
// after the time interval specified by timer-manager.
void schedule(
// Weak pointer to object to check timed out ops.
// tcp_connection_ctx_weak_handle_t = std::weak_ptr< tcp_connection_ctx_base_t >
tcp_connection_ctx_weak_handle_t weak_handle );
// Cancel timeout guard if any.
void cancel();
};
To understand the ground idea behind timer managers it is needed to clarify on
tcp_connection_ctx_base_t
a weak pointer of which is passed to
timer_guard_t::schedule(). A class
tcp_connection_ctx_base_t has a virtual method:
// Check timeouts for all activities.
virtual void check_timeout(
// A handle to itself (eliminates one shared_ptr instantiation).
std::shared_ptr< tcp_connection_ctx_base_t > & self ) = 0;
Internal classes that inherit from tcp_connection_ctx_base_t
implement this
method to initiate a check whether there are a timed out operations. So
timer_guard_t::schedule()
timer guard must simply store a weak pointer to
tcp_connection_ctx_base_t
somewhere and try to invoke check_timeout()
after some period of time that is specified by timer manager. Here is an
example of how to try to invoke check_timeout()
:
// restinio::tcp_connection_ctx_weak_handle_t weak_handle;
if( auto h = weak_handle.lock() )
{
// If here then h is a shared pointer to an exiting object.
h->check_timeout( h );
}
Suppose timer manager sets a time period for checking to 1 second, so each second a context object of a given connection will check if any timeout happened. Between two sequential checks, connection context object may change the actual operation that is tracked for timeout many times.
A timer_guard_t::cancel()
method must cancel scheduled check of a given
timer_guard.
An instance of timer_guard_t
is stored in each connection
managed by RESTinio and to create it timer_manager_t
must define
the following method:
class timer_manager_t
{
public:
// ...
// struct/class timer_guard_t{ ... };
// or
// using timer_guard_t = ...;
// Create guard for connection.
timer_guard_t create_timer_guard();
// ...
};
The second type nested in timer_manager_t
must be factory_t
,
that must implement create(asio::io_context&)
method:
struct factory_t
{
/* Extra parameters for creating timer manager */
auto create( asio::io_context & io_context ) const
{
return std::make_shared< timer_manager_t >( /* params */ );
}
};
Nested factory type is needed for holding parameters of a timer manager that
come from settings. Timer manager itself might need a reference to
asio::io_context
on which server runs, and it is not available on the level
of settings object. So the creation of timer instance is done in two steps. The first
step - the factory is created in server settings and stores params that are needed
for creating timer manager. The second step - when the server is instantiated (hence
asio::io_context
is known) a timer manager is created using the factory.
RESTinio comes with a set of ready-to-use timer_manager_t
implementation:
null_timer_manager_t
– noop timer guards, they produce timer guards that do nothing (when no control needed). See restinio/null_timer_manager.hpp;asio_timer_manager_t
– timer guards implemented with asio timers. See restinio/asio_timer_manager.hpp;so5::so_timer_manager_t
– timer guards implemented with SObjectizer timers. See restinio/so5/so_timer_manager.hpp. Note thatrestinio/so5/so_timer_manager.hpp
header file is not included byrestinio/all.hpp
, so it needs to be included separately.
logger_t
logger_t
- defines a logger implementation.
It must support the following interface:
class null_logger_t
{
public:
template< typename Msg_Builder >
void trace( Msg_Builder && mb );
template< typename Msg_Builder >
void info( Msg_Builder && mb );
template< typename Msg_Builder >
void warn( Msg_Builder && mb );
template< typename Msg_Builder >
void error( Msg_Builder && mb );
};
Msg_Builder
is lambda that returns a message to log out.
This approach allows a compiler to optimize logging when it is possible,
see null_logger_t.
For implementation example see ostream_logger_t.
request_handler_t
request_handler_t
- is a key type for request handling process.
It must be a function-object with the following invocation interface:
restinio::request_handling_status_t
handler( restinio::request_handle_t req );
See Request handler for more details.
strand_t
strand_t
provides serialized callback invocation for events of a specific
connection. There are two option for strand_t
: asio::strand<asio::executor>
or asio::executor
.
By default asio::strand<asio::executor>
is used,
it guarantees serialized chain of callback invocation.
But if asio::io_context
runs on a single thread there is no need
to use asio::strand
because there is no way to run callbacks in parallel.
So in such cases, it is enough to use asio::executor
directly and
eliminate the overhead of asio::strand
.
stream_socket_t
stream_socket_t
allows to customize underlying socket type,
so it possible to create https server using identical interface (see TLS support).