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(
51 engine::current_task::GetTaskProcessor(),
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,
73 impl::SpanLazyPrvalue(std::move(name)),
74 std::forward<Function>(f),
75 std::forward<Args>(args)...
76 );
77}
78
79/// @overload
80/// @ingroup userver_concurrency
81///
82/// Execution of function is guaranteed to start regardless
83/// of engine::TaskProcessor load limits. Prefer utils::Async by default.
84///
85/// @param task_processor Task processor to run on
86/// @param name Name for the tracing::Span to use with this task
87/// @param f Function to execute asynchronously
88/// @param args Arguments to pass to the function
89/// @returns engine::TaskWithResult
90template <typename Function, typename... Args>
91[[nodiscard]] auto CriticalAsync(
92 engine::TaskProcessor& task_processor,
93 std::string name,
94 Function&& f,
95 Args&&... args
96) {
97 return engine::CriticalAsyncNoSpan(
98 task_processor,
99 impl::SpanLazyPrvalue(std::move(name)),
100 std::forward<Function>(f),
101 std::forward<Args>(args)...
102 );
103}
104
105/// @overload
106/// @ingroup userver_concurrency
107///
108/// Execution of function is guaranteed to start regardless
109/// of engine::TaskProcessor load limits. Prefer utils::SharedAsync by default.
110///
111/// @param task_processor Task processor to run on
112/// @param name Name for the tracing::Span to use with this task
113/// @param f Function to execute asynchronously
114/// @param args Arguments to pass to the function
115/// @returns engine::SharedTaskWithResult
116template <typename Function, typename... Args>
117[[nodiscard]] auto SharedCriticalAsync(
118 engine::TaskProcessor& task_processor,
119 std::string name,
120 Function&& f,
121 Args&&... args
122) {
123 return engine::SharedCriticalAsyncNoSpan(
124 task_processor,
125 impl::SpanLazyPrvalue(std::move(name)),
126 std::forward<Function>(f),
127 std::forward<Args>(args)...
128 );
129}
130
131/// @overload
132/// @ingroup userver_concurrency
133///
134/// Task execution may be cancelled before the function starts execution
135/// in case of TaskProcessor overload.
136///
137/// @param task_processor Task processor to run on
138/// @param name Name of the task to show in logs
139/// @param f Function to execute asynchronously
140/// @param args Arguments to pass to the function
141/// @returns engine::SharedTaskWithResult
142template <typename Function, typename... Args>
143[[nodiscard]] auto SharedAsync(engine::TaskProcessor& task_processor, std::string name, Function&& f, Args&&... args) {
144 return engine::SharedAsyncNoSpan(
145 task_processor,
146 impl::SpanLazyPrvalue(std::move(name)),
147 std::forward<Function>(f),
148 std::forward<Args>(args)...
149 );
150}
151
152/// @overload
153/// @ingroup userver_concurrency
154///
155/// Task execution may be cancelled before the function starts execution
156/// in case of TaskProcessor overload.
157///
158/// @param task_processor Task processor to run on
159/// @param name Name of the task to show in logs
160/// @param deadline Deadline to set for the child task, upon reaching it the task will be cancelled
161/// @param f Function to execute asynchronously
162/// @param args Arguments to pass to the function
163/// @returns engine::TaskWithResult
164template <typename Function, typename... Args>
165[[nodiscard]] auto Async(
166 engine::TaskProcessor& task_processor,
167 std::string name,
168 engine::Deadline deadline,
169 Function&& f,
170 Args&&... args
171) {
172 return engine::AsyncNoSpan(
173 task_processor,
174 deadline,
175 impl::SpanLazyPrvalue(std::move(name)),
176 std::forward<Function>(f),
177 std::forward<Args>(args)...
178 );
179}
180
181/// @overload
182/// @ingroup userver_concurrency
183///
184/// Task execution may be cancelled before the function starts execution
185/// in case of TaskProcessor overload.
186///
187/// @param task_processor Task processor to run on
188/// @param name Name of the task to show in logs
189/// @param deadline Deadline to set for the child task, upon reaching it the task will be cancelled
190/// @param f Function to execute asynchronously
191/// @param args Arguments to pass to the function
192/// @returns engine::SharedTaskWithResult
193template <typename Function, typename... Args>
194[[nodiscard]] auto SharedAsync(
195 engine::TaskProcessor& task_processor,
196 std::string name,
197 engine::Deadline deadline,
198 Function&& f,
199 Args&&... args
200) {
201 return engine::SharedAsyncNoSpan(
202 task_processor,
203 deadline,
204 impl::SpanLazyPrvalue(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::Async 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::TaskWithResult
220template <typename Function, typename... Args>
221[[nodiscard]] auto CriticalAsync(std::string name, Function&& f, Args&&... args) {
222 return utils::CriticalAsync(
223 engine::current_task::GetTaskProcessor(),
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/// Execution of function is guaranteed to start regardless
234/// of engine::TaskProcessor load limits. Prefer utils::SharedAsync by default.
235///
236/// @param name Name for the tracing::Span to use with this task
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 SharedCriticalAsync(std::string name, Function&& f, Args&&... args) {
242 return utils::SharedCriticalAsync(
243 engine::current_task::GetTaskProcessor(),
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 f Function to execute asynchronously
258/// @param args Arguments to pass to the function
259/// @returns engine::SharedTaskWithResult
260template <typename Function, typename... Args>
261[[nodiscard]] auto SharedAsync(std::string name, Function&& f, Args&&... args) {
262 return utils::SharedAsync(
263 engine::current_task::GetTaskProcessor(),
264 std::move(name),
265 std::forward<Function>(f),
266 std::forward<Args>(args)...
267 );
268}
269
270/// @overload
271/// @ingroup userver_concurrency
272///
273/// Task execution may be cancelled before the function starts execution
274/// in case of TaskProcessor overload.
275///
276/// @param name Name of the task to show in logs
277/// @param deadline Deadline to set for the child task, upon reaching it the task will be cancelled
278/// @param f Function to execute asynchronously
279/// @param args Arguments to pass to the function
280/// @returns engine::TaskWithResult
281template <typename Function, typename... Args>
282[[nodiscard]] auto Async(std::string name, engine::Deadline deadline, Function&& f, Args&&... args) {
283 return utils::Async(
284 engine::current_task::GetTaskProcessor(),
285 std::move(name),
286 deadline,
287 std::forward<Function>(f),
288 std::forward<Args>(args)...
289 );
290}
291
292/// @overload
293/// @ingroup userver_concurrency
294///
295/// Task execution may be cancelled before the function starts execution
296/// in case of TaskProcessor overload.
297///
298/// @param name Name of the task to show in logs
299/// @param deadline Deadline to set for the child task, upon reaching it the task will be cancelled
300/// @param f Function to execute asynchronously
301/// @param args Arguments to pass to the function
302/// @returns engine::SharedTaskWithResult
303template <typename Function, typename... Args>
304[[nodiscard]] auto SharedAsync(std::string name, engine::Deadline deadline, Function&& f, Args&&... args) {
305 return utils::SharedAsync(
306 engine::current_task::GetTaskProcessor(),
307 std::move(name),
308 deadline,
309 std::forward<Function>(f),
310 std::forward<Args>(args)...
311 );
312}
313
314/// @ingroup userver_concurrency
315///
316/// Starts an asynchronous task without propagating
317/// engine::TaskInheritedVariable. tracing::Span and baggage::Baggage are
318/// inherited. Task execution may be cancelled before the function starts
319/// execution in case of engine::TaskProcessor overload.
320///
321/// Typically used from a request handler to launch tasks that outlive the
322/// request and do not effect its completion.
323///
324/// ## Usage example
325/// Suppose you have some component that runs asynchronous tasks:
326/// @snippet utils/async_test.cpp AsyncBackground component
327/// @snippet utils/async_test.cpp AsyncBackground handler
328///
329/// If the tasks logically belong to the component itself (not to the method
330/// caller), then they should be launched using utils::AsyncBackground instead
331/// of the regular utils::Async
332/// @snippet utils/async_test.cpp AsyncBackground FooAsync
333///
334/// ## Arguments
335/// By default, arguments are copied or moved inside the resulting
336/// `TaskWithResult`, like `std::thread` does. To pass an argument by reference,
337/// wrap it in `std::ref / std::cref` or capture the arguments using a lambda.
338///
339/// @param name Name of the task to show in logs
340/// @param task_processor Task processor to run on
341/// @param f Function to execute asynchronously
342/// @param args Arguments to pass to the function
343/// @returns engine::TaskWithResult
344template <typename Function, typename... Args>
345[[nodiscard]] auto AsyncBackground(
346 std::string name,
347 engine::TaskProcessor& task_processor,
348 Function&& f,
349 Args&&... args
350) {
351 return engine::AsyncNoSpan(
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/// @overload
360/// @ingroup userver_concurrency
361///
362/// Execution of function is guaranteed to start regardless
363/// of engine::TaskProcessor load limits. Use for background tasks for which
364/// failing to start not just breaks handling of a single request, but harms
365/// the whole service instance.
366///
367/// @param name Name of the task to show in logs
368/// @param task_processor Task processor to run on
369/// @param f Function to execute asynchronously
370/// @param args Arguments to pass to the function
371/// @returns engine::TaskWithResult
372template <typename Function, typename... Args>
373[[nodiscard]] auto CriticalAsyncBackground(
374 std::string name,
375 engine::TaskProcessor& task_processor,
376 Function&& f,
377 Args&&... args
378) {
379 return engine::CriticalAsyncNoSpan(
380 task_processor,
381 impl::SpanLazyPrvalue(std::move(name), impl::SpanWrapCall::InheritVariables::kNo),
382 std::forward<Function>(f),
383 std::forward<Args>(args)...
384 );
385}
386
387} // namespace utils
388
389USERVER_NAMESPACE_END