userver: concurrent::BackgroundTaskStorage Class Reference
No Matches
concurrent::BackgroundTaskStorage Class Referencefinal

#include <userver/concurrent/background_task_storage.hpp>

Detailed Description

A storage that allows one to start detached tasks; cancels and waits for unfinished tasks completion at the destructor. Provides CancelAndWait to explicitly cancel tasks (recommended).

Usable for detached tasks that capture references to resources with a limited lifetime. You must guarantee that the resources are available while the BackgroundTaskStorage is alive.

Usage synopsis

std::string x = kString;
std::string y;
// You must guarantee that 'x' and 'y' are alive during 'bts' lifetime.
bts.AsyncDetach("task", [&x, &y] {
y = std::move(x);
// It is recommended to call CancelAndWait explicitly for the clarity of
// tasks' lifetime. BTS destructor calls CancelAndWait implicitly as well.

Lifetime of task's captures

All the advice from utils::Async is applicable here.

BackgroundTaskStorage is always stored as a class field. Tasks that are launched inside it (or moved inside it, for BackgroundTaskStorageCore) can safely access fields declared before it, but not after it:

class Frobnicator {
// ...
void Launch(const Dependencies& stuff);
// ...
Foo foo_;
Bar bar_;
// ...
void Frobnicator::Launch(const Dependencies& stuff) {
int x{};
bts_.AsyncDetach([this, &stuff, &x] {
// BUG! All local variables will be gone.
// They should be captured by move or by copy.
// OK, because foo_ will be destroyed after bts_.
// BUG, because bar_ will be destroyed before bts_.
// Most likely a BUG! Unless `stuff` is contained within other fields,
// there is probably no guarantee that it outlives `bts_`.
// It should have been captured by move or by copy instead.

Generally, it's a good idea to declare bts_ after most other fields to avoid lifetime bugs. An example of fool-proof code:

Foo foo_;
Bar bar_;
// bts_ must be the last field for lifetime reasons.

Components and their clients can always be safely captured by reference:

See also
Component system

So for a BackgroundTaskStorage stored in a component, its tasks can only safely use the fields declared before the BTS field, as well as everything from the components, on which the current component depends.

Definition at line 127 of file background_task_storage.hpp.

Public Member Functions

 BackgroundTaskStorage ()
 BackgroundTaskStorage (engine::TaskProcessor &task_processor)
 Creates a BTS that launches tasks in the specified engine::TaskProcessor.
 BackgroundTaskStorage (const BackgroundTaskStorage &)=delete
BackgroundTaskStorageoperator= (const BackgroundTaskStorage &)=delete
void CancelAndWait () noexcept
void CloseAndWaitDebug () noexcept
template<typename... Args>
void AsyncDetach (std::string name, Args &&... args)
 Launch a task that will be cancelled and waited for in the BTS destructor.
std::int64_t ActiveTasksApprox () const noexcept
 Approximate number of currently active tasks.

Constructor & Destructor Documentation

◆ BackgroundTaskStorage()

concurrent::BackgroundTaskStorage::BackgroundTaskStorage ( )

Creates a BTS that launches tasks in the engine::TaskProcessor used at the BTS creation.

Member Function Documentation

◆ AsyncDetach()

template<typename... Args>
void concurrent::BackgroundTaskStorage::AsyncDetach ( std::string name,
Args &&... args )

Launch a task that will be cancelled and waited for in the BTS destructor.

The task is started as non-Critical, it may be cancelled due to TaskProcessor overload. engine::TaskInheritedVariable instances are not inherited from the caller except baggage::Baggage. See utils::AsyncBackground for details.

Definition at line 155 of file background_task_storage.hpp.

◆ CancelAndWait()

void concurrent::BackgroundTaskStorage::CancelAndWait ( )

Explicitly cancel and wait for the tasks. New tasks must not be launched after this call returns. Should be called no more than once.

◆ CloseAndWaitDebug()

void concurrent::BackgroundTaskStorage::CloseAndWaitDebug ( )

Explicitly stop accepting new tasks and wait for execution tasks in the store. Should be called no more than once.

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