RESTinio
Toggle main menu visibility
Loading...
Searching...
No Matches
restinio
async_chain
fixed_size.hpp
Go to the documentation of this file.
1
/*!
2
* @file
3
* @brief Chain of async handlers of the fixed size.
4
* @since v.0.7.0
5
*/
6
7
#
pragma
once
8
9
#
include
<
restinio
/
async_chain
/
common
.
hpp
>
10
11
#
include
<
array
>
12
13
namespace
restinio
::
async_chain
14
{
15
16
/*!
17
* @brief A holder of fixed-size chain of asynchronous handlers.
18
*
19
* @note
20
* An instance of that type is intended to be filled with actual schedulers
21
* at the creation time. After that new schedulers can't be added to the chain,
22
* and old handlers can't be removed from the chain.
23
*
24
* Usage example for the case when there is no extra-data in a request object
25
* (please note that this is simplified example without actual asynchronous code,
26
* all schedulers work as synchronous handlers):
27
* @code
28
* struct my_traits : public restinio::default_traits_t {
29
* using request_handler_t = restinio::async_chain::fixed_size_chain_t<3>;
30
* };
31
*
32
* // The first handler in the chain.
33
* restinio::async_chain::schedule_result_t headers_checker(
34
* restinio::async_chain::unique_async_handling_controller_t<> controller )
35
* {
36
* ... // Checks values of HTTP-fields and rejects invalid requests.
37
*
38
* // Activation of the next handler.
39
* next( std::move(controller) );
40
*
41
* return restinio::async_chain::ok();
42
* }
43
*
44
* // The second handler in the chain.
45
* restinio::async_chain::schedule_result_t authentificator(
46
* restinio::async_chain::unique_async_handling_controller_t<> controller )
47
* {
48
* ... // Checks user's credentials and rejects requests from
49
* // non-authentificated users.
50
*
51
* // Activation of the next handler.
52
* next( std::move(controller) );
53
*
54
* return restinio::async_chain::ok();
55
* }
56
*
57
* // The last handler in the chain.
58
* restinio::async_chain::schedule_result_t actual_handler(
59
* restinio::async_chain::unique_async_handling_controller_t<> controller )
60
* {
61
* ... // Actual processing.
62
*
63
* return restinio::async_chain::ok();
64
* }
65
*
66
* restinio::run(
67
* on_thread_pool<my_traits>(16)
68
* .address(...)
69
* .port(...)
70
* .request_handler(
71
* // Just enumerate all handlers.
72
* headers_checker,
73
* authentificator,
74
* actual_handler )
75
* );
76
* @endcode
77
*
78
* An instance of `fixed_size_chain_t` can also be created manually and
79
* passed to server's settings by `unique_ptr`:
80
* @code
81
* auto chain = std::make_unique<restinio::async_chain::fixed_size_chain_t<3>>(
82
* headers_checker, authentificator, actual_handler);
83
* ...
84
* restinio::run(
85
* on_thread_pool<my_traits>(16)
86
* .address(...)
87
* .port(...)
88
* .request_handler(std::move(chain))
89
* );
90
* @endcode
91
*
92
* Usage example for the case when some extra-data is incorporated into
93
* a request object
94
* (please note that this is simplified example without actual asynchronous code,
95
* all schedulers work as synchronous handlers):
96
* @code
97
* struct my_extra_data_factory {
98
* // A data formed by checker of HTTP-fields.
99
* struct request_specific_fields_t {...};
100
*
101
* // A data formed by user-authentificator.
102
* struct user_info_t {...};
103
*
104
* // A data to be incorporated into a request object.
105
* using data_t = std::tuple<request_specific_fields_t, user_info_t>;
106
*
107
* void make_within(restinio::extra_data_buffer_t<data_t> buf) {
108
* new(buf.get()) data_t{};
109
* }
110
* };
111
*
112
* struct my_traits : public restinio::default_traits_t {
113
* using extra_data_factory_t = my_extra_data_factory;
114
* using request_handler_t = restinio::async_chain::fixed_size_chain_t<
115
* 3,
116
* extra_data_factory>;
117
* };
118
*
119
* using my_unique_controller_t =
120
* restinio::async_chain::unique_async_handling_controller_t<my_extra_data_factory>;
121
* using my_request_handle_t = my_unique_controller_t::actual_request_handle_t;
122
*
123
* // The first handler in the chain.
124
* restinio::async_chain::schedule_result_t headers_checker(
125
* my_unique_controller_t controller )
126
* {
127
* const my_request_handle_t req = acceptor->request_handle();
128
* ... // Checks values of HTTP-fields and rejects invalid requests.
129
* ...
130
* next( std::move(controller) );
131
* return restinio::async_chain::ok();
132
* }
133
*
134
* // The second handler in the chain.
135
* restinio::async_chain::schedule_result_t authentificator(
136
* my_unique_controller_t controller )
137
* {
138
* const my_request_handle_t req = acceptor->request_handle();
139
* ... // Checks user's credentials and rejects requests from
140
* // non-authentificated users.
141
* ...
142
* next( std::move(controller) );
143
* return restinio::async_chain::ok();
144
* }
145
*
146
* // The last handler in the chain.
147
* restinio::async_chain::schedule_result_t actual_handler(
148
* my_unique_controller_t controller )
149
* {
150
* const my_request_handle_t req = acceptor->request_handle();
151
* auto & field_values = std::get<my_extra_data_factory::request_specific_fields_t>(req->extra_data());
152
* auto & user_info = std::get<my_extra_data_factory::user_info_t>(req->extra_data());
153
* ... // Actual processing.
154
* return restinio::async_chain::ok();
155
* }
156
*
157
* restinio::run(
158
* on_thread_pool<my_traits>(16)
159
* .address(...)
160
* .port(...)
161
* .request_handler(
162
* // Just enumerate all handlers.
163
* headers_checker,
164
* authentificator,
165
* actual_handler )
166
* );
167
* @endcode
168
*
169
* @tparam Size The exact number of schedulers in the chain.
170
*
171
* @tparam Extra_Data_Factory The type of extra-data-factory specified in
172
* the server's traits.
173
*
174
* @since v.0.7.0
175
*/
176
template
<
177
std::size_t Size,
178
typename
Extra_Data_Factory =
no_extra_data_factory_t
>
179
class
fixed_size_chain_t
180
{
181
//! Short alias for unique controller type.
182
using
unique_controller_t
=
unique_async_handling_controller_t
<
Extra_Data_Factory
>;
183
184
//! Short alias for a request handler.
185
using
scheduler_holder_t
=
generic_async_request_scheduler_t
<
Extra_Data_Factory
>;
186
187
//! Short alias for an array of request handlers.
188
using
schedulers_array_t
=
std
::
array
<
scheduler_holder_t
,
Size
>;
189
190
//! Short alias to a smart pointer to the source request.
191
using
actual_request_handle_t
=
192
typename
async_handling_controller_t
< Extra_Data_Factory >::
actual_request_handle_t
;
193
194
//! Short alias for the result of controller's on_next method.
195
using
actual_on_next_result_t
=
196
typename
async_handling_controller_t
< Extra_Data_Factory >::
actual_on_next_result_t
;
197
198
/*!
199
* @brief Actual implementation of the controller interface.
200
*
201
* @note
202
* Object of this type holds a copy of the source array of schedulers.
203
*/
204
class
actual_controller_t
final
205
:
public
async_handling_controller_t
< Extra_Data_Factory >
206
{
207
//! The source request.
208
const
actual_request_handle_t
m_request
;
209
//! Request handlers.
210
schedulers_array_t
m_schedulers
;
211
//! Index of the current scheduler to be used.
212
/*!
213
* @note
214
* May be equal to or greater than m_schedulers.size() in the case
215
* when all handlers are already processed.
216
*/
217
std::size_t
m_current
{};
218
219
public
:
220
//! Initializing constructor.
221
explicit
actual_controller_t
(
222
actual_request_handle_t
request,
223
const
schedulers_array_t & schedulers )
224
:
m_request
{ request }
225
,
m_schedulers
{
schedulers
}
226
{}
227
228
[[nodiscard]]
229
const
actual_request_handle_t
&
230
request_handle
()
const
noexcept
override
{
return
m_request
; }
231
232
private
:
233
[[nodiscard]]
234
actual_on_next_result_t
235
on_next
()
override
236
{
237
const
auto
index_to_use =
m_current
;
238
++
m_current
;
239
240
if
( index_to_use >= m_schedulers.size() )
241
{
242
return
{
no_more_schedulers_t
{} };
243
}
244
else
245
{
246
return
{ m_schedulers[ index_to_use ] };
247
}
248
}
249
};
250
251
//! The array of schedulers.
252
/*!
253
* @note
254
* It's initialized in the constructor and then never changed.
255
*/
256
schedulers_array_t
m_schedulers
;
257
258
//! Helper method to initialize the array of schedulers.
259
template
<
260
typename
Head,
261
typename
... Tail >
262
void
263
store_to
( std::size_t index, Head && head, Tail && ...tail )
264
{
265
m_schedulers[ index ] =
266
[scheduler = std::move(head)]
267
( unique_controller_t controller ) -> schedule_result_t
268
{
269
return
scheduler( std::move(controller) );
270
};
271
272
if
constexpr
( 0u !=
sizeof
...(tail) )
273
store_to( index + 1u, std::forward<Tail>(tail)... );
274
}
275
276
public
:
277
/*!
278
* @attention
279
* The default constructor is disabled. It's because a chain should
280
* be initialized by handlers at the creation time. Because of that
281
* fixed_size_chain_t isn't a DefaultConstructible type.
282
*/
283
fixed_size_chain_t
() =
delete
;
284
285
/*!
286
* @brief Initializing constructor.
287
*
288
* @note
289
* The number of parameters should match the value of @a Size
290
* template parameter.
291
*/
292
template
<
typename
... Schedulers >
293
fixed_size_chain_t
( Schedulers && ...schedulers )
294
{
295
static_assert
( Size ==
sizeof
...(schedulers),
296
"Wrong number of parameters for the constructor of "
297
"fixed_size_chain_t<Size>. Exact `Size` parameters expected"
);
298
299
store_to( 0u, std::forward<Schedulers>(schedulers)... );
300
}
301
302
/*!
303
* Initiates execution of the first scheduler in the chain.
304
*
305
* @note
306
* Always returns request_handling_status_t::accepted.
307
*/
308
[[nodiscard]]
309
request_handling_status_t
310
operator
()(
const
actual_request_handle_t
& req )
const
311
{
312
unique_controller_t controller =
313
std::make_unique< actual_controller_t >(
314
req,
315
m_schedulers );
316
next( std::move(controller) );
317
318
return
request_accepted
(
)
;
319
}
320
};
321
322
}
/* namespace restinio::async_chain */
restinio::async_chain::async_handling_controller_t
Interface of a controller of an async chan.
Definition
common.hpp:146
restinio::async_chain::fixed_size_chain_t::actual_controller_t::m_current
std::size_t m_current
Index of the current scheduler to be used.
Definition
fixed_size.hpp:217
restinio::async_chain::fixed_size_chain_t::actual_controller_t::request_handle
const actual_request_handle_t & request_handle() const noexcept override
Get reference to the source request.
Definition
fixed_size.hpp:230
restinio::async_chain::fixed_size_chain_t::actual_controller_t::actual_controller_t
actual_controller_t(actual_request_handle_t request, const schedulers_array_t &schedulers)
Initializing constructor.
Definition
fixed_size.hpp:221
restinio::async_chain::fixed_size_chain_t::actual_controller_t::m_request
const actual_request_handle_t m_request
The source request.
Definition
fixed_size.hpp:208
restinio::async_chain::fixed_size_chain_t::actual_controller_t::on_next
actual_on_next_result_t on_next() override
Command to try find a next scheduler to be invoked.
Definition
fixed_size.hpp:235
restinio::async_chain::fixed_size_chain_t::actual_controller_t::m_schedulers
schedulers_array_t m_schedulers
Request handlers.
Definition
fixed_size.hpp:210
restinio::async_chain::fixed_size_chain_t
A holder of fixed-size chain of asynchronous handlers.
Definition
fixed_size.hpp:180
restinio::async_chain::fixed_size_chain_t::m_schedulers
schedulers_array_t m_schedulers
The array of schedulers.
Definition
fixed_size.hpp:256
restinio::async_chain::fixed_size_chain_t::fixed_size_chain_t
fixed_size_chain_t(Schedulers &&...schedulers)
Initializing constructor.
Definition
fixed_size.hpp:293
restinio::async_chain::fixed_size_chain_t::fixed_size_chain_t
fixed_size_chain_t()=delete
restinio::async_chain::fixed_size_chain_t::operator()
request_handling_status_t operator()(const actual_request_handle_t &req) const
Definition
fixed_size.hpp:310
restinio::async_chain::fixed_size_chain_t::actual_on_next_result_t
typename async_handling_controller_t< Extra_Data_Factory >::actual_on_next_result_t actual_on_next_result_t
Short alias for the result of controller's on_next method.
Definition
fixed_size.hpp:195
restinio::async_chain::fixed_size_chain_t::actual_request_handle_t
typename async_handling_controller_t< Extra_Data_Factory >::actual_request_handle_t actual_request_handle_t
Short alias to a smart pointer to the source request.
Definition
fixed_size.hpp:191
restinio::async_chain::fixed_size_chain_t::store_to
void store_to(std::size_t index, Head &&head, Tail &&...tail)
Helper method to initialize the array of schedulers.
Definition
fixed_size.hpp:263
restinio::async_chain
Definition
common.hpp:12
restinio
Definition
sendfile_operation_default.ipp:12
restinio::request_accepted
constexpr request_handling_status_t request_accepted() noexcept
Definition
common_types.hpp:46
restinio::request_handling_status_t
request_handling_status_t
Request handling status.
Definition
common_types.hpp:26
restinio::async_chain::no_more_schedulers_t
Special type to be used as an indicator that there are no more schedulers in an async chain.
Definition
common.hpp:106
restinio::no_extra_data_factory_t
The default extra-data-factory to be used in server's traits if a user doesn't specify own one.
Definition
request_handler.hpp:78
Generated by
1.17.0