userver: userver/utils/async.hpp Source File
Loading...
Searching...
No Matches
async.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/utils/async.hpp
4/// @brief Utility functions to start asynchronous tasks.
5
6#include <string>
7#include <utility>
8
9#include <userver/engine/async.hpp>
10#include <userver/utils/impl/span_wrap_call.hpp>
11
12USERVER_NAMESPACE_BEGIN
13
14namespace utils {
15
16/// @ingroup userver_concurrency
17///
18/// @brief Starts an asynchronous task.
19///
20/// By default, arguments are copied or moved inside the resulting
21/// `TaskWithResult`, like `std::thread` does. To pass an argument by reference,
22/// wrap it in `std::ref / std::cref` or capture the arguments using a lambda.
23///
24/// For more documentation on launching asynchronous tasks:
25///
26/// @see @ref intro_tasks
27///
28/// ## About this specific overload
29///
30/// This is the overload that should be used by default.
31///
32/// * The task will be launched on the current TaskProcessor.
33/// * Only 1 task may call `Wait` or `Get` on this task.
34/// * The task may be cancelled before the function starts execution
35/// in case of TaskProcessor overload. Also, if the task is cancelled for any
36/// reason before the function starts execution, it will not run at all.
37/// * The task will create a child tracing::Span with the specified name
38/// * The task will inherit all engine::TaskInheritedVariable instances
39/// from the current task.
40///
41/// For details on the various other overloads:
42/// @see @ref flavors_of_async
43///
44/// @param name Name of the task to show in logs
45/// @param f Function to execute asynchronously
46/// @param args Arguments to pass to the function
47/// @returns engine::TaskWithResult
48template <typename Function, typename... Args>
49[[nodiscard]] auto Async(std::string name, Function&& f, Args&&... args) {
50 return engine::AsyncNoSpan(
52 impl::SpanLazyPrvalue(std::move(name)),
53 std::forward<Function>(f),
54 std::forward<Args>(args)...
55 );
56}
57
58/// @overload
59/// @ingroup userver_concurrency
60///
61/// Task execution may be cancelled before the function starts execution
62/// in case of TaskProcessor overload.
63///
64/// @param task_processor Task processor to run on
65/// @param name Name of the task to show in logs
66/// @param f Function to execute asynchronously
67/// @param args Arguments to pass to the function
68/// @returns engine::TaskWithResult
69template <typename Function, typename... Args>
70[[nodiscard]] auto Async(engine::TaskProcessor& task_processor, std::string name, Function&& f, Args&&... args) {
71 return engine::AsyncNoSpan(
72 task_processor, impl::SpanLazyPrvalue(std::move(name)), std::forward<Function>(f), std::forward<Args>(args)...
73 );
74}
75
76/// @overload
77/// @ingroup userver_concurrency
78///
79/// Execution of function is guaranteed to start regardless
80/// of engine::TaskProcessor load limits. Prefer utils::Async by default.
81///
82/// @param task_processor Task processor to run on
83/// @param name Name for the tracing::Span to use with this task
84/// @param f Function to execute asynchronously
85/// @param args Arguments to pass to the function
86/// @returns engine::TaskWithResult
87template <typename Function, typename... Args>
88[[nodiscard]] auto
89CriticalAsync(engine::TaskProcessor& task_processor, std::string name, Function&& f, Args&&... args) {
90 return engine::CriticalAsyncNoSpan(
91 task_processor, impl::SpanLazyPrvalue(std::move(name)), std::forward<Function>(f), std::forward<Args>(args)...
92 );
93}
94
95/// @overload
96/// @ingroup userver_concurrency
97///
98/// Execution of function is guaranteed to start regardless
99/// of engine::TaskProcessor load limits. Prefer utils::SharedAsync by default.
100///
101/// @param task_processor Task processor to run on
102/// @param name Name for the tracing::Span to use with this task
103/// @param f Function to execute asynchronously
104/// @param args Arguments to pass to the function
105/// @returns engine::SharedTaskWithResult
106template <typename Function, typename... Args>
107[[nodiscard]] auto
108SharedCriticalAsync(engine::TaskProcessor& task_processor, std::string name, Function&& f, Args&&... args) {
109 return engine::SharedCriticalAsyncNoSpan(
110 task_processor, impl::SpanLazyPrvalue(std::move(name)), std::forward<Function>(f), std::forward<Args>(args)...
111 );
112}
113
114/// @overload
115/// @ingroup userver_concurrency
116///
117/// Task execution may be cancelled before the function starts execution
118/// in case of TaskProcessor overload.
119///
120/// @param task_processor Task processor to run on
121/// @param name Name of the task to show in logs
122/// @param f Function to execute asynchronously
123/// @param args Arguments to pass to the function
124/// @returns engine::SharedTaskWithResult
125template <typename Function, typename... Args>
126[[nodiscard]] auto SharedAsync(engine::TaskProcessor& task_processor, std::string name, Function&& f, Args&&... args) {
127 return engine::SharedAsyncNoSpan(
128 task_processor, impl::SpanLazyPrvalue(std::move(name)), std::forward<Function>(f), std::forward<Args>(args)...
129 );
130}
131
132/// @overload
133/// @ingroup userver_concurrency
134///
135/// Task execution may be cancelled before the function starts execution
136/// in case of TaskProcessor overload.
137///
138/// @param task_processor Task processor to run on
139/// @param name Name of the task to show in logs
140/// @param deadline Deadline to set for the child task, upon reaching it the task will be cancelled
141/// @param f Function to execute asynchronously
142/// @param args Arguments to pass to the function
143/// @returns engine::TaskWithResult
144template <typename Function, typename... Args>
145[[nodiscard]] auto Async(
146 engine::TaskProcessor& task_processor,
147 std::string name,
148 engine::Deadline deadline,
149 Function&& f,
150 Args&&... args
151) {
152 return engine::AsyncNoSpan(
153 task_processor,
154 deadline,
155 impl::SpanLazyPrvalue(std::move(name)),
156 std::forward<Function>(f),
157 std::forward<Args>(args)...
158 );
159}
160
161/// @overload
162/// @ingroup userver_concurrency
163///
164/// Task execution may be cancelled before the function starts execution
165/// in case of TaskProcessor overload.
166///
167/// @param task_processor Task processor to run on
168/// @param name Name of the task to show in logs
169/// @param deadline Deadline to set for the child task, upon reaching it the task will be cancelled
170/// @param f Function to execute asynchronously
171/// @param args Arguments to pass to the function
172/// @returns engine::SharedTaskWithResult
173template <typename Function, typename... Args>
174[[nodiscard]] auto SharedAsync(
175 engine::TaskProcessor& task_processor,
176 std::string name,
177 engine::Deadline deadline,
178 Function&& f,
179 Args&&... args
180) {
181 return engine::SharedAsyncNoSpan(
182 task_processor,
183 deadline,
184 impl::SpanLazyPrvalue(std::move(name)),
185 std::forward<Function>(f),
186 std::forward<Args>(args)...
187 );
188}
189
190/// @overload
191/// @ingroup userver_concurrency
192///
193/// Execution of function is guaranteed to start regardless
194/// of engine::TaskProcessor load limits. Prefer utils::Async by default.
195///
196/// @param name Name for the tracing::Span to use with this task
197/// @param f Function to execute asynchronously
198/// @param args Arguments to pass to the function
199/// @returns engine::TaskWithResult
200template <typename Function, typename... Args>
201[[nodiscard]] auto CriticalAsync(std::string name, Function&& f, Args&&... args) {
202 return utils::CriticalAsync(
204 std::move(name),
205 std::forward<Function>(f),
206 std::forward<Args>(args)...
207 );
208}
209
210/// @overload
211/// @ingroup userver_concurrency
212///
213/// Execution of function is guaranteed to start regardless
214/// of engine::TaskProcessor load limits. Prefer utils::SharedAsync by default.
215///
216/// @param name Name for the tracing::Span to use with this task
217/// @param f Function to execute asynchronously
218/// @param args Arguments to pass to the function
219/// @returns engine::SharedTaskWithResult
220template <typename Function, typename... Args>
221[[nodiscard]] auto SharedCriticalAsync(std::string name, Function&& f, Args&&... args) {
222 return utils::SharedCriticalAsync(
224 std::move(name),
225 std::forward<Function>(f),
226 std::forward<Args>(args)...
227 );
228}
229
230/// @overload
231/// @ingroup userver_concurrency
232///
233/// Task execution may be cancelled before the function starts execution
234/// in case of TaskProcessor overload.
235///
236/// @param name Name of the task to show in logs
237/// @param f Function to execute asynchronously
238/// @param args Arguments to pass to the function
239/// @returns engine::SharedTaskWithResult
240template <typename Function, typename... Args>
241[[nodiscard]] auto SharedAsync(std::string name, Function&& f, Args&&... args) {
242 return utils::SharedAsync(
244 std::move(name),
245 std::forward<Function>(f),
246 std::forward<Args>(args)...
247 );
248}
249
250/// @overload
251/// @ingroup userver_concurrency
252///
253/// Task execution may be cancelled before the function starts execution
254/// in case of TaskProcessor overload.
255///
256/// @param name Name of the task to show in logs
257/// @param deadline Deadline to set for the child task, upon reaching it the task will be cancelled
258/// @param f Function to execute asynchronously
259/// @param args Arguments to pass to the function
260/// @returns engine::TaskWithResult
261template <typename Function, typename... Args>
262[[nodiscard]] auto Async(std::string name, engine::Deadline deadline, Function&& f, Args&&... args) {
263 return utils::Async(
265 std::move(name),
266 deadline,
267 std::forward<Function>(f),
268 std::forward<Args>(args)...
269 );
270}
271
272/// @overload
273/// @ingroup userver_concurrency
274///
275/// Task execution may be cancelled before the function starts execution
276/// in case of TaskProcessor overload.
277///
278/// @param name Name of the task to show in logs
279/// @param deadline Deadline to set for the child task, upon reaching it the task will be cancelled
280/// @param f Function to execute asynchronously
281/// @param args Arguments to pass to the function
282/// @returns engine::SharedTaskWithResult
283template <typename Function, typename... Args>
284[[nodiscard]] auto SharedAsync(std::string name, engine::Deadline deadline, Function&& f, Args&&... args) {
285 return utils::SharedAsync(
287 std::move(name),
288 deadline,
289 std::forward<Function>(f),
290 std::forward<Args>(args)...
291 );
292}
293
294/// @ingroup userver_concurrency
295///
296/// Starts an asynchronous task without propagating
297/// engine::TaskInheritedVariable. tracing::Span and baggage::Baggage are
298/// inherited. Task execution may be cancelled before the function starts
299/// execution in case of engine::TaskProcessor overload.
300///
301/// Typically used from a request handler to launch tasks that outlive the
302/// request and do not effect its completion.
303///
304/// ## Usage example
305/// Suppose you have some component that runs asynchronous tasks:
306/// @snippet utils/async_test.cpp AsyncBackground component
307/// @snippet utils/async_test.cpp AsyncBackground handler
308///
309/// If the tasks logically belong to the component itself (not to the method
310/// caller), then they should be launched using utils::AsyncBackground instead
311/// of the regular utils::Async
312/// @snippet utils/async_test.cpp AsyncBackground FooAsync
313///
314/// ## Arguments
315/// By default, arguments are copied or moved inside the resulting
316/// `TaskWithResult`, like `std::thread` does. To pass an argument by reference,
317/// wrap it in `std::ref / std::cref` or capture the arguments using a lambda.
318///
319/// @param name Name of the task to show in logs
320/// @param task_processor Task processor to run on
321/// @param f Function to execute asynchronously
322/// @param args Arguments to pass to the function
323/// @returns engine::TaskWithResult
324template <typename Function, typename... Args>
325[[nodiscard]] auto
326AsyncBackground(std::string name, engine::TaskProcessor& task_processor, Function&& f, Args&&... args) {
327 return engine::AsyncNoSpan(
328 task_processor,
329 impl::SpanLazyPrvalue(std::move(name), impl::SpanWrapCall::InheritVariables::kNo),
330 std::forward<Function>(f),
331 std::forward<Args>(args)...
332 );
333}
334
335/// @overload
336/// @ingroup userver_concurrency
337///
338/// Execution of function is guaranteed to start regardless
339/// of engine::TaskProcessor load limits. Use for background tasks for which
340/// failing to start not just breaks handling of a single request, but harms
341/// the whole service instance.
342///
343/// @param name Name of the task to show in logs
344/// @param task_processor Task processor to run on
345/// @param f Function to execute asynchronously
346/// @param args Arguments to pass to the function
347/// @returns engine::TaskWithResult
348template <typename Function, typename... Args>
349[[nodiscard]] auto
350CriticalAsyncBackground(std::string name, engine::TaskProcessor& task_processor, Function&& f, Args&&... args) {
351 return engine::CriticalAsyncNoSpan(
352 task_processor,
353 impl::SpanLazyPrvalue(std::move(name), impl::SpanWrapCall::InheritVariables::kNo),
354 std::forward<Function>(f),
355 std::forward<Args>(args)...
356 );
357}
358
359} // namespace utils
360
361USERVER_NAMESPACE_END