userver
C++ Async Framework
Toggle main menu visibility
Loading...
Searching...
No Matches
conflated_event_channel.hpp
Go to the documentation of this file.
1
#
pragma
once
2
3
/// @file userver/concurrent/conflated_event_channel.hpp
4
/// @brief @copybrief concurrent::ConflatedEventChannel
5
6
#
include
<
atomic
>
7
#
include
<
vector
>
8
9
#
include
<
userver
/
concurrent
/
async_event_channel
.
hpp
>
10
#
include
<
userver
/
engine
/
single_consumer_event
.
hpp
>
11
#
include
<
userver
/
engine
/
task
/
task_with_result
.
hpp
>
12
13
USERVER_NAMESPACE_BEGIN
14
15
namespace
concurrent
{
16
17
/// @ingroup userver_concurrency
18
///
19
/// @brief A non-blocking version of 'AsyncEventChannel'
20
///
21
/// The difference is that 'SendEvent' returns immediately, without waiting for
22
/// subscribers to finish. If 'SendEvent' is called multiple times while
23
/// subscribers are handling the previous event, new events will be conflated
24
/// (all events except for the last one will be ignored). This class can be used
25
/// instead of 'AsyncEventChannel' when we've got a "heavy" subscriber and we
26
/// don't want to slow down the pipeline.
27
class
ConflatedEventChannel
:
private
AsyncEventChannel
<> {
28
public
:
29
explicit
ConflatedEventChannel(std::string name, OnRemoveCallback on_listener_removal = {});
30
~ConflatedEventChannel() override;
31
32
/// For convenient forwarding of events from other channels
33
template
<
typename
... Args>
34
void
AddChannel
(
concurrent
::
AsyncEventSource
<Args...>& channel);
35
36
using
AsyncEventChannel
<>::AddListener;
37
38
/// Subscribes to updates using a member function. Also immediately invokes
39
/// the function with the current config snapshot.
40
///
41
/// Further updates are delivered after @ref utils::ResourceScopeStorage::AfterConstruction, including those updates
42
/// that arrived before it. Unsubscribe runs in @ref utils::ResourceScopeStorage::BeforeDestruction.
43
///
44
/// @param scopes storage that owns the subscription lifetime. In a component constructor pass `context.Scopes()`
45
/// or @ref components::GetResourceScopes.
46
template
<
typename
Class>
47
void
UpdateAndListen
(
utils
::ResourceScopeStorage& scopes, Class* obj, std::string_view name,
void
(Class::*func)());
48
49
/// @overload
50
/// @deprecated Use the overload that takes @ref utils::ResourceScopeStorage.
51
///
52
/// Store the returned scope as a member and call `Unsubscribe` explicitly.
53
template
<
typename
Class>
54
concurrent
::AsyncEventSubscriberScope
UpdateAndListen
(Class* obj, std::string_view name,
void
(Class::*func)());
55
56
void
SendEvent();
57
58
private
:
59
template
<
typename
... Args>
60
void
OnChannelEvent(Args...);
61
62
std::atomic<
bool
> stop_flag_;
63
engine::
TaskWithResult
<
void
> task_;
64
std::vector<
concurrent
::AsyncEventSubscriberScope> subscriptions_;
65
engine::SingleConsumerEvent event_;
66
};
67
68
template
<
typename
... Args>
69
void
ConflatedEventChannel
::
AddChannel
(
concurrent
::
AsyncEventSource
<Args...>& channel) {
70
subscriptions_.push_back(channel.AddListener(
this
,
Name
(
)
, &
ConflatedEventChannel
::OnChannelEvent<Args...>));
71
}
72
73
template
<
typename
Class>
74
void
ConflatedEventChannel
::
UpdateAndListen
(
75
utils
::ResourceScopeStorage& scopes,
76
Class* obj,
77
std::string_view name,
78
void
(Class::*func)()
79
) {
80
DoUpdateAndListenScoped(scopes, obj, name, func, [obj, func] { (obj->*func)(); });
81
}
82
83
template
<
typename
Class>
84
concurrent
::AsyncEventSubscriberScope
ConflatedEventChannel
::
UpdateAndListen
(
85
Class* obj,
86
std::string_view name,
87
void
(Class::*func)()
88
) {
89
return
DoUpdateAndListen(obj, name, func, [&] { (obj->*func)(); });
90
}
91
92
template
<
typename
... Args>
93
void
ConflatedEventChannel
::OnChannelEvent(Args...) {
94
SendEvent();
95
}
96
97
}
// namespace concurrent
98
99
USERVER_NAMESPACE_END
userver
concurrent
conflated_event_channel.hpp
Generated on
for userver by
Doxygen
1.17.0