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
11USERVER_NAMESPACE_BEGIN
12
13namespace engine::io {
14class RwBase;
15} // namespace engine::io
16
17namespace server::request {
18
19class ResponseDataAccounter final {
20 public:
21 void StartRequest(size_t size,
22 std::chrono::steady_clock::time_point create_time);
23
24 void StopRequest(size_t size,
25 std::chrono::steady_clock::time_point create_time);
26
27 size_t GetCurrentLevel() const { return current_; }
28
29 size_t GetMaxLevel() const { return max_; }
30
31 void SetMaxLevel(size_t size) { max_ = size; }
32
33 std::chrono::milliseconds GetAvgRequestTime() const;
34
35 private:
36 std::atomic<size_t> current_{0};
37 std::atomic<size_t> max_{std::numeric_limits<size_t>::max()};
38 std::atomic<size_t> count_{0};
39 std::atomic<size_t> time_sum_{0};
40};
41
42/// @brief Base class for all the server responses.
43class ResponseBase {
44 public:
45 explicit ResponseBase(ResponseDataAccounter& data_accounter);
46 ResponseBase(const ResponseBase&) = delete;
47 ResponseBase(ResponseBase&&) = delete;
48 virtual ~ResponseBase() noexcept;
49
50 void SetData(std::string data);
51 const std::string& GetData() const { return data_; }
52
53 virtual bool IsBodyStreamed() const = 0;
54 virtual bool WaitForHeadersEnd() = 0;
55 virtual void SetHeadersEnd() = 0;
56
57 /// @cond
58 // TODO: server internals. remove from public interface
59 void SetReady();
60 void SetReady(std::chrono::steady_clock::time_point now);
61 virtual void SetSendFailed(
62 std::chrono::steady_clock::time_point failure_time);
63 bool IsLimitReached() const;
64
65 bool IsReady() const { return is_ready_; }
66 bool IsSent() const { return is_sent_; }
67 size_t BytesSent() const { return bytes_sent_; }
68 std::chrono::steady_clock::time_point ReadyTime() const {
69 return ready_time_;
70 }
71 std::chrono::steady_clock::time_point SentTime() const { return sent_time_; }
72
73 virtual void SendResponse(engine::io::RwBase& socket) = 0;
74
75 virtual void SetStatusServiceUnavailable() = 0;
76 virtual void SetStatusOk() = 0;
77 virtual void SetStatusNotFound() = 0;
78 /// @endcond
79
80 protected:
81 void SetSent(std::size_t bytes_sent,
82 std::chrono::steady_clock::time_point sent_time);
83
84 private:
85 class Guard final {
86 public:
87 Guard(ResponseDataAccounter& accounter,
88 std::chrono::steady_clock::time_point create_time, size_t size)
89 : accounter_(accounter), create_time_(create_time), size_(size) {
90 accounter_.StartRequest(size_, create_time_);
91 }
92
93 ~Guard() { accounter_.StopRequest(size_, create_time_); }
94
95 private:
96 ResponseDataAccounter& accounter_;
97 std::chrono::steady_clock::time_point create_time_;
98 size_t size_;
99 };
100
101 ResponseDataAccounter& accounter_;
102 std::optional<Guard> guard_;
103 std::string data_;
104 std::chrono::steady_clock::time_point create_time_;
105 std::chrono::steady_clock::time_point ready_time_;
106 std::chrono::steady_clock::time_point sent_time_;
107 size_t bytes_sent_ = 0;
108 bool is_ready_ = false;
109 bool is_sent_ = false;
110};
111
112} // namespace server::request
113
114USERVER_NAMESPACE_END