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},
32 std::forward<Function>(f),
33 std::forward<Args>(args)...
34 )};
35}
36
37} // namespace impl
38
39/// @brief Runs an asynchronous function call using the specified task processor.
40///
41/// @warning If any logs are written in the task function (outside any manual tracing::Span scopes),
42/// then those logs will have no `span_id` (yikes!).
43/// If you create a span there manually, it will be disconnected from the outside trace.
44/// **Prefer utils::Async by default instead.**
45///
46/// @warning To hide a spammy span from traces, use @ref tracing::Span::CurrentSpan plus
47/// @ref tracing::Span::SetLogLevel instead.
48/// Logs will then be linked to the nearest span that is written out.
49///
50/// @warning Some clients may call tracing::Span::CurrentSpan unconditionally, so don't be too surprised
51/// if they won't work without a span scope. Do write tests.
52///
53/// `AsyncNoSpan` is useful for:
54/// * implementing periodic tasks (like utils::PeriodicTask);
55/// * worker tasks that typically run until service shutdown, and it makes no sense to have a span for the task itself;
56/// * some low-level (e.g. driver or filesystem-IO) code where logs are definitely not written;
57/// * breaking traces e.g. this is (rarely) wanted for some background tasks.
58///
59/// @see utils::Async for main documentation on `Async` function family.
60template <typename Function, typename... Args>
61[[nodiscard]] auto AsyncNoSpan(TaskProcessor& task_processor, Function&& f, Args&&... args) {
62 return impl::MakeTaskWithResult<TaskWithResult>(
63 task_processor,
65 {},
66 std::forward<Function>(f),
67 std::forward<Args>(args)...
68 );
69}
70
71/// @overload
72template <typename Function, typename... Args>
73[[nodiscard]] auto SharedAsyncNoSpan(TaskProcessor& task_processor, Function&& f, Args&&... args) {
74 return impl::MakeTaskWithResult<SharedTaskWithResult>(
75 task_processor,
77 {},
78 std::forward<Function>(f),
79 std::forward<Args>(args)...
80 );
81}
82
83/// @overload
84template <typename Function, typename... Args>
85[[nodiscard]] auto AsyncNoSpan(TaskProcessor& task_processor, Deadline deadline, Function&& f, Args&&... args) {
86 return impl::MakeTaskWithResult<TaskWithResult>(
87 task_processor,
89 deadline,
90 std::forward<Function>(f),
91 std::forward<Args>(args)...
92 );
93}
94
95/// @overload
96template <typename Function, typename... Args>
97[[nodiscard]] auto SharedAsyncNoSpan(TaskProcessor& task_processor, Deadline deadline, Function&& f, Args&&... args) {
98 return impl::MakeTaskWithResult<SharedTaskWithResult>(
99 task_processor,
101 deadline,
102 std::forward<Function>(f),
103 std::forward<Args>(args)...
104 );
105}
106
107/// @overload
108template <typename Function, typename... Args>
109[[nodiscard]] auto AsyncNoSpan(Function&& f, Args&&... args) {
110 return AsyncNoSpan(current_task::GetTaskProcessor(), std::forward<Function>(f), std::forward<Args>(args)...);
111}
112
113/// @overload
114template <typename Function, typename... Args>
115[[nodiscard]] auto SharedAsyncNoSpan(Function&& f, Args&&... args) {
116 return SharedAsyncNoSpan(current_task::GetTaskProcessor(), std::forward<Function>(f), std::forward<Args>(args)...);
117}
118
119/// @overload
120template <typename Function, typename... Args>
121[[nodiscard]] auto AsyncNoSpan(Deadline deadline, Function&& f, Args&&... args) {
122 return AsyncNoSpan(
124 deadline,
125 std::forward<Function>(f),
126 std::forward<Args>(args)...
127 );
128}
129
130/// @overload
131template <typename Function, typename... Args>
132[[nodiscard]] auto SharedAsyncNoSpan(Deadline deadline, Function&& f, Args&&... args) {
133 return SharedAsyncNoSpan(
135 deadline,
136 std::forward<Function>(f),
137 std::forward<Args>(args)...
138 );
139}
140
141/// @overload
142/// @see Task::Importance::Critical
143template <typename Function, typename... Args>
144[[nodiscard]] auto CriticalAsyncNoSpan(TaskProcessor& task_processor, Function&& f, Args&&... args) {
145 return impl::MakeTaskWithResult<TaskWithResult>(
146 task_processor,
148 {},
149 std::forward<Function>(f),
150 std::forward<Args>(args)...
151 );
152}
153
154/// @overload
155/// @see Task::Importance::Critical
156template <typename Function, typename... Args>
157[[nodiscard]] auto SharedCriticalAsyncNoSpan(TaskProcessor& task_processor, Function&& f, Args&&... args) {
158 return impl::MakeTaskWithResult<SharedTaskWithResult>(
159 task_processor,
161 {},
162 std::forward<Function>(f),
163 std::forward<Args>(args)...
164 );
165}
166
167/// @overload
168/// @see Task::Importance::Critical
169template <typename Function, typename... Args>
170[[nodiscard]] auto CriticalAsyncNoSpan(Function&& f, Args&&... args) {
171 return CriticalAsyncNoSpan(
173 std::forward<Function>(f),
174 std::forward<Args>(args)...
175 );
176}
177
178/// @overload
179/// @see Task::Importance::Critical
180template <typename Function, typename... Args>
181[[nodiscard]] auto SharedCriticalAsyncNoSpan(Function&& f, Args&&... args) {
182 return SharedCriticalAsyncNoSpan(
184 std::forward<Function>(f),
185 std::forward<Args>(args)...
186 );
187}
188
189/// @overload
190/// @see Task::Importance::Critical
191template <typename Function, typename... Args>
192[[nodiscard]] auto CriticalAsyncNoSpan(Deadline deadline, Function&& f, Args&&... args) {
193 return impl::MakeTaskWithResult<TaskWithResult>(
196 deadline,
197 std::forward<Function>(f),
198 std::forward<Args>(args)...
199 );
200}
201
202} // namespace engine
203
204USERVER_NAMESPACE_END