userver: userver/server/request/response_base.hpp Source File
⚠️ This is the documentation for an old userver version. Click here to switch to the latest version.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
response_base.hpp
1#pragma once
2
3#include <atomic>
4#include <chrono>
5#include <functional>
6#include <limits>
7#include <optional>
8#include <string>
9#include <unordered_map>
10
11#include <userver/concurrent/striped_counter.hpp>
12#include <userver/utils/fast_pimpl.hpp>
13
14USERVER_NAMESPACE_BEGIN
15
16namespace engine::io {
17class RwBase;
18} // namespace engine::io
19
20namespace server::request {
21
22class ResponseDataAccounter final {
23 public:
24 void StartRequest(size_t size,
25 std::chrono::steady_clock::time_point create_time);
26
27 void StopRequest(size_t size,
28 std::chrono::steady_clock::time_point create_time);
29
30 size_t GetCurrentLevel() const { return current_; }
31
32 size_t GetMaxLevel() const { return max_; }
33
34 void SetMaxLevel(size_t size) { max_ = size; }
35
36 std::chrono::milliseconds GetAvgRequestTime() const;
37
38 private:
39 std::atomic<size_t> current_{0};
40 std::atomic<size_t> max_{std::numeric_limits<size_t>::max()};
41 concurrent::StripedCounter count_;
42 concurrent::StripedCounter time_sum_;
43};
44
45/// @brief Base class for all the server responses.
46class ResponseBase {
47 public:
48 explicit ResponseBase(ResponseDataAccounter& data_accounter);
49 ResponseBase(const ResponseBase&) = delete;
50 ResponseBase(ResponseBase&&) = delete;
51 virtual ~ResponseBase() noexcept;
52
53 void SetData(std::string data);
54 const std::string& GetData() const { return data_; }
55
56 virtual bool IsBodyStreamed() const = 0;
57 virtual bool WaitForHeadersEnd() = 0;
58 virtual void SetHeadersEnd() = 0;
59
60 /// @cond
61 // TODO: server internals. remove from public interface
62 void SetReady();
63 void SetReady(std::chrono::steady_clock::time_point now);
64 virtual void SetSendFailed(
65 std::chrono::steady_clock::time_point failure_time);
66 bool IsLimitReached() const;
67
68 bool IsReady() const { return is_ready_; }
69 bool IsSent() const { return is_sent_; }
70 size_t BytesSent() const { return bytes_sent_; }
71 std::chrono::steady_clock::time_point ReadyTime() const {
72 return ready_time_;
73 }
74 std::chrono::steady_clock::time_point SentTime() const { return sent_time_; }
75
76 virtual void SendResponse(engine::io::RwBase& socket) = 0;
77
78 virtual void SetStatusServiceUnavailable() = 0;
79 virtual void SetStatusOk() = 0;
80 virtual void SetStatusNotFound() = 0;
81 /// @endcond
82
83 protected:
84 ResponseBase(ResponseDataAccounter& data_account,
85 std::chrono::steady_clock::time_point now);
86
87 void SetSent(std::size_t bytes_sent,
88 std::chrono::steady_clock::time_point sent_time);
89
90 private:
91 class Guard final {
92 public:
93 Guard(ResponseDataAccounter& accounter,
94 std::chrono::steady_clock::time_point create_time, size_t size)
95 : accounter_(accounter), create_time_(create_time), size_(size) {
96 accounter_.StartRequest(size_, create_time_);
97 }
98
99 ~Guard() { accounter_.StopRequest(size_, create_time_); }
100
101 private:
102 ResponseDataAccounter& accounter_;
103 std::chrono::steady_clock::time_point create_time_;
104 size_t size_;
105 };
106
107 ResponseDataAccounter& accounter_;
108 std::optional<Guard> guard_;
109 std::string data_;
110 std::chrono::steady_clock::time_point create_time_;
111 std::chrono::steady_clock::time_point ready_time_;
112 std::chrono::steady_clock::time_point sent_time_;
113 size_t bytes_sent_ = 0;
114 bool is_ready_ = false;
115 bool is_sent_ = false;
116};
117
118} // namespace server::request
119
120USERVER_NAMESPACE_END