userver: utils::ResourceScopeStorage Class Reference
Loading...
Searching...
No Matches
utils::ResourceScopeStorage Class Referencefinal

#include <userver/utils/resource_scopes.hpp>

Detailed Description

Defers subscription and callback registration until the object is fully constructed.

Components often register external subscriptions (statistics writers, config listeners, and similar) that capture this and run later on another thread. Registering them directly in the constructor is unsafe: the callback may fire before the constructor finishes and observe partially initialized fields. Unregistering in the destructor is equally unsafe if the callback can still run while members are already being destroyed.

During construction, call Register to queue a functor that performs the actual registration. The component system calls AfterConstruction when the constructor (including derived classes) has completed, and BeforeDestruction before the destructor body runs. That way registration callbacks see a fully built object, and unregistration runs before members used by the callback are torn down.

The same storage is available from components::ComponentContext::Scopes in components, or as a standalone helper in unit tests and WithResourceScopes.

static std::vector<int> trace;
// Reset static variables for --gtest_repeat.
trace = {};
class ComponentWithResource final : public components::ComponentBase {
public:
ComponentWithResource(const components::ComponentConfig& config, const components::ComponentContext& context)
: components::ComponentBase(config, context)
{
trace.push_back(0);
context.Scopes().Register([] {
trace.push_back(1);
return utils::FastScopeGuard([]() noexcept { trace.push_back(2); });
});
context.Scopes().Register([] {
trace.push_back(3);
return utils::FastScopeGuard([]() noexcept { trace.push_back(4); });
});
}
};
auto component_list = components::MinimalComponentList().Append<ComponentWithResource>("component");
EXPECT_THAT(trace, ::testing::ElementsAre(0, 1, 3, 4, 2));

Definition at line 85 of file resource_scopes.hpp.

Public Member Functions

 ResourceScopeStorage (ResourceScopeStorage &&other) noexcept=default
 
ResourceScopeStorageoperator= (ResourceScopeStorage &&other) noexcept=default
 
template<std::invocable<> AfterConstructionCallback>
void Register (AfterConstructionCallback after_construction)
 Registers a functor to register some resource that will be called after the component is successfully created (including all class descendants) or after the component creation is emulated in unit tests. The functor must return a RAII-style handle object that unregisters the previously registered resource. The returned handle's destructor is called just before the component destructor is called.
 
void AfterConstruction ()
 Call all registered functors.
 
void BeforeDestruction ()
 Unregister all previously registered resources.
 

Member Function Documentation

◆ Register()

template<std::invocable<> AfterConstructionCallback>
void utils::ResourceScopeStorage::Register ( AfterConstructionCallback after_construction)
inline

Registers a functor to register some resource that will be called after the component is successfully created (including all class descendants) or after the component creation is emulated in unit tests. The functor must return a RAII-style handle object that unregisters the previously registered resource. The returned handle's destructor is called just before the component destructor is called.

Note
callback is not called if the component is not created OR any previously registered callback throws an exception.
if you don't have an existing RAII-ish class, but still want to do a cleanup, you might want to use utils::FastScopeGuard to wrap the cleanup function.

Definition at line 105 of file resource_scopes.hpp.


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