userver: userver/server/request/task_inherited_data.hpp Source File
Loading...
Searching...
No Matches
task_inherited_data.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/server/request/task_inherited_data.hpp
4/// @brief @copybrief server::request::TaskInheritedData
5
6#include <atomic>
7#include <chrono>
8#include <optional>
9#include <string>
10
11#include <userver/engine/deadline.hpp>
12#include <userver/engine/task/inherited_variable.hpp>
13
14USERVER_NAMESPACE_BEGIN
15
16/// Server request related types and functions
17namespace server::request {
18
19/// Microsecond-precision system-clock instant (e.g. from `X-Request-Deadline`).
20using TaskInheritedOriginalDeadline = std::chrono::time_point<std::chrono::system_clock, std::chrono::microseconds>;
21
22/// @brief Signals when an operation has detected deadline expiration.
23class DeadlineSignal final {
24public:
25 DeadlineSignal() noexcept;
26 DeadlineSignal(const DeadlineSignal&) noexcept;
27 DeadlineSignal& operator=(const DeadlineSignal&) noexcept;
28
29 void SetExpired() noexcept;
30 bool IsExpired() const noexcept;
31
32private:
33 std::atomic<bool> value_{false};
34};
35
36/// @brief Per-request data that should be available inside handlers
37struct TaskInheritedData final {
38 /// The static path of the handler
39 std::string_view path;
40
41 /// The method of the request
42 std::string_view method;
43
44 /// The time when the request started being handled
45 std::chrono::steady_clock::time_point start_time{};
46
47 /// The time when there is no use handling the request anymore
48 engine::Deadline deadline;
49
50 /// Signals when an operation has detected deadline expiration
51 mutable DeadlineSignal deadline_signal{};
52
53 /// Original absolute deadline parsed from `X-Request-Deadline` header.
54 /// Intended solely for propagation to downstream services; use @ref deadline for the task deadline.
55 std::optional<TaskInheritedOriginalDeadline> original_deadline = std::nullopt;
56};
57
58/// @see TaskInheritedData for details on the contents.
59extern engine::TaskInheritedVariable<TaskInheritedData> kTaskInheritedData;
60
61/// @brief Returns TaskInheritedData::deadline, or an unreachable
62/// engine::Deadline if none was set.
63/// @note Use this method to set the deadline for tasks.
64engine::Deadline GetTaskInheritedDeadline() noexcept;
65
66/// @brief Returns TaskInheritedData::original_deadline, or std::nullopt if the header was absent or invalid.
67/// @warning Do not use this method to set the deadline for tasks. It is intended for deadline propagation only.
68/// Use @ref GetTaskInheritedDeadline() to set the deadline for tasks.
69std::optional<TaskInheritedOriginalDeadline> GetTaskInheritedOriginalDeadline() noexcept;
70
71/// @brief Marks that the current TaskInheritedData::deadline has expired.
73
74/// @brief Stops deadline propagation within its scope
75///
76/// By default, handler deadline is honored in requests created directly
77/// from the handler task, as well as from its child tasks. However, some
78/// requests need to be completed regardless of whether the initial request
79/// timed out, because they are needed for something other than forming the
80/// upstream response.
81///
82/// Deadline propagation is automatically blocked in tasks launched using:
83/// @see concurrent::BackgroundTaskStorage::AsyncDetach
84/// @see utils::AsyncBackground
85///
86/// @see concurrent::BackgroundTaskStorage::AsyncDetach does it by default.
87class [[nodiscard]] DeadlinePropagationBlocker final {
88public:
89 DeadlinePropagationBlocker();
90
91 DeadlinePropagationBlocker(DeadlinePropagationBlocker&&) = delete;
92 DeadlinePropagationBlocker& operator=(DeadlinePropagationBlocker&&) = delete;
93 ~DeadlinePropagationBlocker();
94
95private:
96 TaskInheritedData old_value_;
97};
98
99} // namespace server::request
100
101USERVER_NAMESPACE_END