userver: concurrent::AsyncEventChannel< Args > Class Template Reference
Loading...
Searching...
No Matches
concurrent::AsyncEventChannel< Args > Class Template Referenceabstract

#include <userver/concurrent/async_event_channel.hpp>

Detailed Description

template<typename... Args>
class concurrent::AsyncEventChannel< Args >

AsyncEventChannel is an in-process pub-sub with strict FIFO serialization, i.e. only after the event was processed a new event may appear for processing, same listener is never called concurrently.

Example usage:

enum class WeatherKind { kSunny, kRainy };
class WeatherStorage final {
public:
explicit WeatherStorage(WeatherKind value)
: value_(value), channel_("weather") {}
WeatherKind Get() const { return value_.load(); }
concurrent::AsyncEventSource<WeatherKind>& GetSource() { return channel_; }
template <typename Class>
Class* obj, std::string_view name, void (Class::*func)(WeatherKind)) {
return channel_.DoUpdateAndListen(obj, name, func,
[&] { (obj->*func)(Get()); });
}
void Set(WeatherKind value) {
value_.store(value);
channel_.SendEvent(value);
}
private:
std::atomic<WeatherKind> value_;
};
enum class CoatKind { kJacket, kRaincoat };
class CoatStorage final {
public:
explicit CoatStorage(WeatherStorage& weather_storage) {
weather_subscriber_ = weather_storage.UpdateAndListen(
this, "coats", &CoatStorage::OnWeatherUpdate);
}
~CoatStorage() { weather_subscriber_.Unsubscribe(); }
CoatKind Get() const { return value_.load(); }
private:
void OnWeatherUpdate(WeatherKind weather) {
value_.store(ComputeCoat(weather));
}
static CoatKind ComputeCoat(WeatherKind weather);
std::atomic<CoatKind> value_{};
};
UTEST(AsyncEventChannel, UpdateAndListenSample) {
WeatherStorage weather_storage(WeatherKind::kSunny);
CoatStorage coat_storage(weather_storage);
EXPECT_EQ(coat_storage.Get(), CoatKind::kJacket);
weather_storage.Set(WeatherKind::kRainy);
EXPECT_EQ(coat_storage.Get(), CoatKind::kRaincoat);
}

Definition at line 74 of file async_event_channel.hpp.

+ Inheritance diagram for concurrent::AsyncEventChannel< Args >:

Public Types

using Function = typename AsyncEventSource<Args...>::Function
 
using OnRemoveCallback = std::function<void(Function&)>
 

Public Member Functions

 AsyncEventChannel (std::string_view name)
 The primary constructor.
 
 AsyncEventChannel (std::string_view name, OnRemoveCallback on_listener_removal)
 The constructor with AsyncEventSubscriberScope usage checking.
 
template<typename UpdaterFunc >
AsyncEventSubscriberScope DoUpdateAndListen (FunctionId id, std::string_view name, Function &&func, UpdaterFunc &&updater)
 For use in UpdateAndListen of specific event channels.
 
template<typename Class , typename UpdaterFunc >
AsyncEventSubscriberScope DoUpdateAndListen (Class *obj, std::string_view name, void(Class::*func)(Args...), UpdaterFunc &&updater)
 This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.
 
void SendEvent (Args... args) const
 
const std::string & Name () const noexcept
 
AsyncEventSubscriberScope AddListener (Class *obj, std::string_view name, void(Class::*func)(Args...))
 Subscribes to updates from this event source.
 
AsyncEventSubscriberScope AddListener (FunctionId id, std::string_view name, Function &&func)
 A type-erased version of AddListener.
 

Protected Member Functions

virtual AsyncEventSubscriberScope DoAddListener (FunctionId id, std::string_view name, Function &&func)=0
 

Member Typedef Documentation

◆ Function

template<typename... Args>
using concurrent::AsyncEventChannel< Args >::Function = typename AsyncEventSource<Args...>::Function

Definition at line 76 of file async_event_channel.hpp.

◆ OnRemoveCallback

template<typename... Args>
using concurrent::AsyncEventChannel< Args >::OnRemoveCallback = std::function<void(Function&)>

Definition at line 77 of file async_event_channel.hpp.

Constructor & Destructor Documentation

◆ AsyncEventChannel() [1/2]

template<typename... Args>
concurrent::AsyncEventChannel< Args >::AsyncEventChannel ( std::string_view name)
inlineexplicit

The primary constructor.

Parameters
nameused for diagnostic purposes and is also accessible with Name

Definition at line 81 of file async_event_channel.hpp.

◆ AsyncEventChannel() [2/2]

template<typename... Args>
concurrent::AsyncEventChannel< Args >::AsyncEventChannel ( std::string_view name,
OnRemoveCallback on_listener_removal )
inline

The constructor with AsyncEventSubscriberScope usage checking.

The constructor with a callback that is called on listener removal. The callback takes a reference to ‘Function’ as input. This is useful for checking the lifetime of data captured by the listener update function.

Note
Works only in debug mode.
Warning
Data captured by on_listener_removal function must be valid until the AsyncEventChannel object is completely destroyed.

Example usage:

auto on_remove = [](std::function<void(int)> func) { func(1); };
concurrent::AsyncEventChannel<int> channel("channel", on_remove);
int value = 0;
{
channel.AddListener(concurrent::FunctionId(&sub), "sub",
[&value](int new_value) { value = new_value; });
}
if constexpr (concurrent::impl::kCheckSubscriptionUB) {
EXPECT_EQ(value, 1);
} else {
EXPECT_EQ(value, 0);
}
Parameters
nameused for diagnostic purposes and is also accessible with Name
on_listener_removalthe callback used for check
See also
impl::CheckDataUsedByCallbackHasNotBeenDestroyedBeforeUnsubscribing

Definition at line 102 of file async_event_channel.hpp.

Member Function Documentation

◆ AddListener() [1/2]

AsyncEventSubscriberScope concurrent::AsyncEventSource< Args >::AddListener ( Class * obj,
std::string_view name,
void(Class::*)(Args...) func )
inlineinherited

Subscribes to updates from this event source.

The listener won't be called immediately. To process the current value and then listen to updates, use UpdateAndListen of specific event channels.

Warning
Listeners should not be added or removed while processing the event inside another listener.

Example usage:

UTEST(AsyncEventChannel, AddListenerSample) {
WeatherStorage weather_storage(WeatherKind::kSunny);
std::vector<WeatherKind> recorded_weather;
weather_storage.GetSource().AddListener(
concurrent::FunctionId(&recorder), "recorder",
[&](WeatherKind weather) { recorded_weather.push_back(weather); });
weather_storage.Set(WeatherKind::kRainy);
weather_storage.Set(WeatherKind::kSunny);
weather_storage.Set(WeatherKind::kSunny);
EXPECT_EQ(recorded_weather,
(std::vector{WeatherKind::kRainy, WeatherKind::kSunny,
WeatherKind::kSunny}));
recorder.Unsubscribe();
}
Parameters
objthe subscriber, which is the owner of the listener method, and is also used as the unique identifier of the subscription for this AsyncEventSource
namethe name of the subscriber, for diagnostic purposes
functhe listener method, usually called On<DataName>Update, e.g. OnConfigUpdate or OnCacheUpdate
Returns
a AsyncEventSubscriberScope controlling the subscription, which should be stored as a member in the subscriber; Unsubscribe should be called explicitly

Definition at line 129 of file async_event_source.hpp.

◆ AddListener() [2/2]

AsyncEventSubscriberScope concurrent::AsyncEventSource< Args >::AddListener ( FunctionId id,
std::string_view name,
Function && func )
inlineinherited

A type-erased version of AddListener.

Parameters
idthe unique identifier of the subscription
namethe name of the subscriber, for diagnostic purposes
functhe callback used for event notifications

Definition at line 140 of file async_event_source.hpp.

◆ DoUpdateAndListen() [1/2]

template<typename... Args>
template<typename Class , typename UpdaterFunc >
AsyncEventSubscriberScope concurrent::AsyncEventChannel< Args >::DoUpdateAndListen ( Class * obj,
std::string_view name,
void(Class::*)(Args...) func,
UpdaterFunc && updater )
inline

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Definition at line 123 of file async_event_channel.hpp.

◆ DoUpdateAndListen() [2/2]

template<typename... Args>
template<typename UpdaterFunc >
AsyncEventSubscriberScope concurrent::AsyncEventChannel< Args >::DoUpdateAndListen ( FunctionId id,
std::string_view name,
Function && func,
UpdaterFunc && updater )
inline

For use in UpdateAndListen of specific event channels.

Atomically calls updater, which should invoke func with the previously sent event, and subscribes to new events as if using AddListener.

See also
AsyncEventSource::AddListener

Definition at line 112 of file async_event_channel.hpp.

◆ Name()

template<typename... Args>
const std::string & concurrent::AsyncEventChannel< Args >::Name ( ) const
inlinenoexcept
Returns
the name of this event channel

Definition at line 158 of file async_event_channel.hpp.

◆ SendEvent()

template<typename... Args>
void concurrent::AsyncEventChannel< Args >::SendEvent ( Args... args) const
inline

Send the next event and wait until all the listeners process it.

Strict FIFO serialization is guaranteed, i.e. only after this event is processed a new event may be delivered for the subscribers, same listener/subscriber is never called concurrently.

Definition at line 137 of file async_event_channel.hpp.


The documentation for this class was generated from the following file: