userver: userver/engine/async.hpp Source File
Loading...
Searching...
No Matches
async.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/engine/async.hpp
4/// @brief Low-level TaskWithResult creation helpers
5
6#include <userver/engine/deadline.hpp>
7#include <userver/engine/impl/task_context_factory.hpp>
8#include <userver/engine/task/shared_task_with_result.hpp>
9#include <userver/engine/task/task_processor_fwd.hpp>
10#include <userver/engine/task/task_with_result.hpp>
11#include <userver/utils/impl/wrapped_call.hpp>
12
13USERVER_NAMESPACE_BEGIN
14
15namespace engine {
16
17namespace impl {
18
19template <template <typename> typename TaskType, typename Function, typename... Args>
20[[nodiscard]] auto MakeTaskWithResult(
21 TaskProcessor& task_processor,
22 Task::Importance importance,
23 Deadline deadline,
24 Function&& f,
25 Args&&... args
26) {
27 using ResultType = typename utils::impl::WrappedCallImplType<Function, Args...>::ResultType;
28 constexpr auto kWaitMode = TaskType<ResultType>::kWaitMode;
29
30 return TaskType<ResultType>{MakeTask(
31 {task_processor, importance, kWaitMode, deadline}, std::forward<Function>(f), std::forward<Args>(args)...
32 )};
33}
34
35} // namespace impl
36
37/// @brief Runs an asynchronous function call using the specified task processor.
38///
39/// @warning If any logs are written in the task function (outside any manual tracing::Span scopes),
40/// then those logs will have no `span_id` (yikes!).
41/// If you create a span there manually, it will be disconnected from the outside trace.
42/// **Prefer utils::Async by default instead.**
43///
44/// @warning To hide a spammy span from traces, use @ref tracing::Span::CurrentSpan plus
45/// @ref tracing::Span::SetLogLevel instead.
46/// Logs will then be linked to the nearest span that is written out.
47///
48/// @warning Some clients may call tracing::Span::CurrentSpan unconditionally, so don't be too surprised
49/// if they won't work without a span scope. Do write tests.
50///
51/// `AsyncNoSpan` is useful for:
52/// * implementing periodic tasks (like utils::PeriodicTask);
53/// * worker tasks that typically run until service shutdown, and it makes no sense to have a span for the task itself;
54/// * some low-level (e.g. driver or filesystem-IO) code where logs are definitely not written;
55/// * breaking traces e.g. this is (rarely) wanted for some background tasks.
56///
57/// @see utils::Async for main documentation on `Async` function family.
58template <typename Function, typename... Args>
59[[nodiscard]] auto AsyncNoSpan(TaskProcessor& task_processor, Function&& f, Args&&... args) {
60 return impl::MakeTaskWithResult<TaskWithResult>(
61 task_processor, Task::Importance::kNormal, {}, std::forward<Function>(f), std::forward<Args>(args)...
62 );
63}
64
65/// @overload
66template <typename Function, typename... Args>
67[[nodiscard]] auto SharedAsyncNoSpan(TaskProcessor& task_processor, Function&& f, Args&&... args) {
68 return impl::MakeTaskWithResult<SharedTaskWithResult>(
69 task_processor, Task::Importance::kNormal, {}, std::forward<Function>(f), std::forward<Args>(args)...
70 );
71}
72
73/// @overload
74template <typename Function, typename... Args>
75[[nodiscard]] auto AsyncNoSpan(TaskProcessor& task_processor, Deadline deadline, Function&& f, Args&&... args) {
76 return impl::MakeTaskWithResult<TaskWithResult>(
77 task_processor, Task::Importance::kNormal, deadline, std::forward<Function>(f), std::forward<Args>(args)...
78 );
79}
80
81/// @overload
82template <typename Function, typename... Args>
83[[nodiscard]] auto SharedAsyncNoSpan(TaskProcessor& task_processor, Deadline deadline, Function&& f, Args&&... args) {
84 return impl::MakeTaskWithResult<SharedTaskWithResult>(
85 task_processor, Task::Importance::kNormal, deadline, std::forward<Function>(f), std::forward<Args>(args)...
86 );
87}
88
89/// @overload
90template <typename Function, typename... Args>
91[[nodiscard]] auto AsyncNoSpan(Function&& f, Args&&... args) {
92 return AsyncNoSpan(current_task::GetTaskProcessor(), std::forward<Function>(f), std::forward<Args>(args)...);
93}
94
95/// @overload
96template <typename Function, typename... Args>
97[[nodiscard]] auto SharedAsyncNoSpan(Function&& f, Args&&... args) {
98 return SharedAsyncNoSpan(current_task::GetTaskProcessor(), std::forward<Function>(f), std::forward<Args>(args)...);
99}
100
101/// @overload
102template <typename Function, typename... Args>
103[[nodiscard]] auto AsyncNoSpan(Deadline deadline, Function&& f, Args&&... args) {
104 return AsyncNoSpan(
105 current_task::GetTaskProcessor(), deadline, std::forward<Function>(f), std::forward<Args>(args)...
106 );
107}
108
109/// @overload
110template <typename Function, typename... Args>
111[[nodiscard]] auto SharedAsyncNoSpan(Deadline deadline, Function&& f, Args&&... args) {
112 return SharedAsyncNoSpan(
113 current_task::GetTaskProcessor(), deadline, std::forward<Function>(f), std::forward<Args>(args)...
114 );
115}
116
117/// @overload
118/// @see Task::Importance::Critical
119template <typename Function, typename... Args>
120[[nodiscard]] auto CriticalAsyncNoSpan(TaskProcessor& task_processor, Function&& f, Args&&... args) {
121 return impl::MakeTaskWithResult<TaskWithResult>(
122 task_processor, Task::Importance::kCritical, {}, std::forward<Function>(f), std::forward<Args>(args)...
123 );
124}
125
126/// @overload
127/// @see Task::Importance::Critical
128template <typename Function, typename... Args>
129[[nodiscard]] auto SharedCriticalAsyncNoSpan(TaskProcessor& task_processor, Function&& f, Args&&... args) {
130 return impl::MakeTaskWithResult<SharedTaskWithResult>(
131 task_processor, Task::Importance::kCritical, {}, std::forward<Function>(f), std::forward<Args>(args)...
132 );
133}
134
135/// @overload
136/// @see Task::Importance::Critical
137template <typename Function, typename... Args>
138[[nodiscard]] auto CriticalAsyncNoSpan(Function&& f, Args&&... args) {
139 return CriticalAsyncNoSpan(
140 current_task::GetTaskProcessor(), std::forward<Function>(f), std::forward<Args>(args)...
141 );
142}
143
144/// @overload
145/// @see Task::Importance::Critical
146template <typename Function, typename... Args>
147[[nodiscard]] auto SharedCriticalAsyncNoSpan(Function&& f, Args&&... args) {
148 return SharedCriticalAsyncNoSpan(
149 current_task::GetTaskProcessor(), std::forward<Function>(f), std::forward<Args>(args)...
150 );
151}
152
153/// @overload
154/// @see Task::Importance::Critical
155template <typename Function, typename... Args>
156[[nodiscard]] auto CriticalAsyncNoSpan(Deadline deadline, Function&& f, Args&&... args) {
157 return impl::MakeTaskWithResult<TaskWithResult>(
160 deadline,
161 std::forward<Function>(f),
162 std::forward<Args>(args)...
163 );
164}
165
166} // namespace engine
167
168USERVER_NAMESPACE_END