-
Notifications
You must be signed in to change notification settings - Fork 45
/
pub.hpp
298 lines (252 loc) · 6.58 KB
/
pub.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
/*
SObjectizer 5.
*/
/*!
\file
\brief Functions for creating and binding to the active group dispatcher.
*/
#pragma once
#include <so_5/declspec.hpp>
#include <so_5/disp_binder.hpp>
#include <so_5/nonempty_name.hpp>
#include <so_5/disp/mpsc_queue_traits/pub.hpp>
#include <so_5/disp/reuse/work_thread_activity_tracking.hpp>
#include <so_5/disp/reuse/work_thread_factory_params.hpp>
#include <string>
#include <string_view>
namespace so_5
{
namespace disp
{
namespace active_group
{
/*!
* \brief Alias for namespace with traits of event queue.
*
* \since
* v.5.5.10
*/
namespace queue_traits = so_5::disp::mpsc_queue_traits;
//
// disp_params_t
//
/*!
* \brief Parameters for active group dispatcher.
*
* \since
* v.5.5.10
*/
class disp_params_t
: public so_5::disp::reuse::work_thread_activity_tracking_flag_mixin_t< disp_params_t >
, public so_5::disp::reuse::work_thread_factory_mixin_t< disp_params_t >
{
using activity_tracking_mixin_t = so_5::disp::reuse::
work_thread_activity_tracking_flag_mixin_t< disp_params_t >;
using thread_factory_mixin_t = so_5::disp::reuse::
work_thread_factory_mixin_t< disp_params_t >;
public :
//! Default constructor.
disp_params_t() = default;
friend inline void
swap( disp_params_t & a, disp_params_t & b ) noexcept
{
swap(
static_cast< activity_tracking_mixin_t & >(a),
static_cast< activity_tracking_mixin_t & >(b) );
swap(
static_cast< work_thread_factory_mixin_t & >(a),
static_cast< work_thread_factory_mixin_t & >(b) );
swap( a.m_queue_params, b.m_queue_params );
}
//! Setter for queue parameters.
disp_params_t &
set_queue_params( queue_traits::queue_params_t p )
{
m_queue_params = std::move(p);
return *this;
}
//! Tuner for queue parameters.
/*!
* Accepts lambda-function or functional object which tunes
* queue parameters.
\code
so_5::disp::active_group::make_dispatcher( env,
"my_active_group_disp",
so_5::disp::active_group::disp_params_t{}.tune_queue_params(
[]( so_5::disp::active_group::queue_traits::queue_params_t & p ) {
p.lock_factory( so_5::disp::active_group::queue_traits::simple_lock_factory() );
} ) );
\endcode
*/
template< typename L >
disp_params_t &
tune_queue_params( L tunner )
{
tunner( m_queue_params );
return *this;
}
//! Getter for queue parameters.
const queue_traits::queue_params_t &
queue_params() const
{
return m_queue_params;
}
private :
//! Queue parameters.
queue_traits::queue_params_t m_queue_params;
};
namespace impl {
class actual_dispatcher_iface_t;
//
// basic_dispatcher_iface_t
//
/*!
* \brief The very basic interface of %active_group dispatcher.
*
* This class contains a minimum that is necessary for implementation
* of dispatcher_handle class.
*
* \since
* v.5.6.0
*/
class basic_dispatcher_iface_t
: public std::enable_shared_from_this<actual_dispatcher_iface_t>
{
public :
virtual ~basic_dispatcher_iface_t() noexcept = default;
[[nodiscard]]
virtual disp_binder_shptr_t
binder( nonempty_name_t group_name ) = 0;
};
using basic_dispatcher_iface_shptr_t =
std::shared_ptr< basic_dispatcher_iface_t >;
class dispatcher_handle_maker_t;
} /* namespace impl */
//
// dispatcher_handle_t
//
/*!
* \since
* v.5.6.0
*
* \brief A handle for %active_group dispatcher.
*/
class [[nodiscard]] dispatcher_handle_t
{
friend class impl::dispatcher_handle_maker_t;
//! A reference to actual implementation of a dispatcher.
impl::basic_dispatcher_iface_shptr_t m_dispatcher;
dispatcher_handle_t(
impl::basic_dispatcher_iface_shptr_t dispatcher ) noexcept
: m_dispatcher{ std::move(dispatcher) }
{}
//! Is this handle empty?
bool
empty() const noexcept { return !m_dispatcher; }
public :
dispatcher_handle_t() noexcept = default;
//! Get a binder for that dispatcher.
/*!
* \attention
* An attempt to call this method on empty handle is UB.
*/
[[nodiscard]]
disp_binder_shptr_t
binder(
//! Name of group for a new agent.
nonempty_name_t group_name ) const
{
return m_dispatcher->binder( std::move(group_name) );
}
//! Is this handle empty?
operator bool() const noexcept { return empty(); }
//! Does this handle contain a reference to dispatcher?
bool
operator!() const noexcept { return !empty(); }
//! Drop the content of handle.
void
reset() noexcept { m_dispatcher.reset(); }
};
/*!
* \brief Create an instance of %active_group dispatcher.
*
* \par Usage sample
\code
auto disp = so_5::disp::active_group::make_dispatcher(
env,
"request_handler",
// Additional params with specific options for queue's traits.
so_5::disp::active_group::disp_params_t{}.tune_queue_params(
[]( so_5::disp::active_group::queue_traits::queue_params_t & p ) {
p.lock_factory( so_5::disp::active_obj::queue_traits::simple_lock_factory() );
} ) );
auto coop = env.make_coop(
// The main dispatcher for that coop will be
// this instance of active_group dispatcher.
disp.binder( "request_handler" ) );
\endcode
*
* \since
* v.5.6.0
*/
SO_5_FUNC dispatcher_handle_t
make_dispatcher(
//! SObjectizer Environment to work in.
so_5::environment_t & env,
//! Value for creating names of data sources for
//! run-time monitoring.
const std::string_view data_sources_name_base,
//! Parameters for dispatcher.
disp_params_t params );
/*!
* \brief Create an instance of %active_group dispatcher.
*
* \par Usage sample
\code
auto disp = so_5::disp::active_group::make_dispatcher(
env,
"long_req_handlers" );
auto coop = env.make_coop(
// The main dispatcher for that coop will be
// this instance of active_group dispatcher.
disp.binder( "passive_objects" ) );
\endcode
*
* \since
* v.5.6.0
*/
inline dispatcher_handle_t
make_dispatcher(
//! SObjectizer Environment to work in.
so_5::environment_t & env,
//! Value for creating names of data sources for
//! run-time monitoring.
const std::string_view data_sources_name_base )
{
return make_dispatcher( env, data_sources_name_base, disp_params_t{} );
}
/*!
* \brief Create an instance of %active_group dispatcher.
*
* \par Usage sample
\code
auto disp = so_5::disp::active_group::make_dispatcher( env );
auto coop = env.make_coop(
// The main dispatcher for that coop will be
// this instance of active_group dispatcher.
disp.binder( "passive_objects" ) );
\endcode
*
* \since
* v.5.6.0
*/
inline dispatcher_handle_t
make_dispatcher(
//! SObjectizer Environment to work in.
so_5::environment_t & env )
{
return make_dispatcher( env, std::string_view{} );
}
} /* namespace active_group */
} /* namespace disp */
} /* namespace so_5 */