userver
C++ Async Framework
Toggle main menu visibility
Loading...
Searching...
No Matches
response_base.hpp
Go to the documentation of this file.
1
#
pragma
once
2
3
/// @file userver/server/request/response_base.hpp
4
/// @brief @copybrief server::request::ResponseBase
5
6
#
include
<
atomic
>
7
#
include
<
chrono
>
8
#
include
<
functional
>
9
#
include
<
limits
>
10
#
include
<
memory
>
11
#
include
<
optional
>
12
#
include
<
string
>
13
#
include
<
string_view
>
14
#
include
<
variant
>
15
16
#
include
<
userver
/
concurrent
/
queue
.
hpp
>
17
#
include
<
userver
/
concurrent
/
striped_counter
.
hpp
>
18
#
include
<
userver
/
engine
/
single_consumer_event
.
hpp
>
19
#
include
<
userver
/
utils
/
fast_pimpl
.
hpp
>
20
21
USERVER_NAMESPACE_BEGIN
22
23
/// @cond
24
// TODO: server internals. remove from a public interface
25
namespace
server::
http
::impl {
26
27
struct
Http2StreamEvent {
28
std::int32_t stream_id{-1};
29
std::string body_part{};
30
bool
is_end{
false
};
31
};
32
33
// The order is fifo in the context of a single producer. So we are tolerant to
34
// reordering between producers
35
using
Http2StreamEventQueue =
concurrent
::
NonFifoMpscQueue
<Http2StreamEvent>;
36
37
class
Http2StreamEventProducer
final
{
38
public
:
39
Http2StreamEventProducer(Http2StreamEventQueue& queue, engine::SingleConsumerEvent& event);
40
41
void
PushEvent(Http2StreamEvent event, engine::Deadline deadline
=
{
}
);
42
43
void
CloseStream(std::int32_t id);
44
45
private
:
46
Http2StreamEventQueue::Producer producer_;
47
engine::SingleConsumerEvent& event_;
48
};
49
50
}
// namespace server::http::impl
51
/// @endcond
52
53
namespace
engine::
io
{
54
class
RwBase
;
55
}
// namespace engine::io
56
57
namespace
server::
request
{
58
59
namespace
impl {
60
61
class
ChunkStorage
final
{
62
public
:
63
ChunkStorage() =
default
;
64
explicit
ChunkStorage(std::string data);
65
explicit
ChunkStorage(std::shared_ptr<
const
std::string> data);
66
67
ChunkStorage(
const
ChunkStorage&) =
delete
;
68
ChunkStorage(ChunkStorage&&)
noexcept
=
default
;
69
ChunkStorage& operator=(
const
ChunkStorage&) =
delete
;
70
ChunkStorage& operator=(ChunkStorage&&)
noexcept
=
default
;
71
72
bool
Empty()
const
noexcept
;
73
std::size_t Size()
const
noexcept
;
74
std::string_view View()
const
noexcept
;
75
const
std::string& AsString()
const
;
76
77
private
:
78
std::variant<std::string, std::shared_ptr<
const
std::string>> storage_{};
79
};
80
81
}
// namespace impl
82
83
class
ResponseDataAccounter
final
{
84
public
:
85
void
StartRequest(std::chrono::steady_clock::time_point create_time);
86
87
void
StopRequest(std::size_t size, std::chrono::steady_clock::time_point create_time);
88
89
void
ReaccountRequest(
90
std::size_t old_size,
91
std::chrono::steady_clock::time_point old_create_time,
92
std::size_t new_size,
93
std::chrono::steady_clock::time_point new_create_time
94
);
95
96
std::size_t GetPendingResponsesSizeInBytes()
const
{
return
pending_responses_size_in_bytes_; }
97
98
std::size_t GetPendingResponsesCount()
const
{
return
pending_responses_count_
.
NonNegativeRead
(
)
; }
99
100
std::size_t GetMaxPendingResponsesSizeInBytes()
const
{
return
max_pending_responses_size_in_bytes_; }
101
102
void
SetMaxPendingResponsesSizeInBytes(size_t size) { max_pending_responses_size_in_bytes_ = size; }
103
104
std::chrono::milliseconds GetAvgRequestTime()
const
;
105
106
private
:
107
std::atomic<std::size_t> pending_responses_size_in_bytes_{0};
108
std::atomic<std::size_t> max_pending_responses_size_in_bytes_{std::numeric_limits<std::size_t>::max()};
109
concurrent
::StripedCounter pending_responses_count_
{
}
;
110
concurrent
::StripedCounter time_sum_
{
}
;
111
};
112
113
// TODO: merge with HttpResponse
114
115
/// @brief Base class for all the server responses.
116
class
ResponseBase
{
117
public
:
118
explicit
ResponseBase(ResponseDataAccounter& data_accounter);
119
ResponseBase(
const
ResponseBase
&) =
delete
;
120
ResponseBase(
ResponseBase
&&) =
delete
;
121
virtual
~ResponseBase()
noexcept
;
122
123
void
SetData(std::string data);
124
/// @brief Sets response body without copying, keeping @a data alive.
125
/// Useful for serving cached static content.
126
void
SetSharedData
(std::shared_ptr<
const
std::string> data);
127
const
std::string& GetData()
const
;
128
/// @cond
129
// For internal use only.
130
impl::ChunkStorage ExtractData();
131
/// @endcond
132
133
virtual
bool
IsBodyStreamed()
const
= 0;
134
virtual
bool
WaitForHeadersEnd() = 0;
135
virtual
void
SetHeadersEnd() = 0;
136
137
/// @cond
138
// TODO: server internals. remove from a public interface
139
void
SetReady();
140
void
SetReady(std::chrono::steady_clock::time_point now);
141
bool
IsLimitReached()
const
;
142
143
bool
IsReady()
const
noexcept
{
return
ready_time_ != kUnset; }
144
bool
IsSent()
const
noexcept
{
return
is_sent_; }
145
std::size_t GetBytesSent()
const
noexcept
{
return
bytes_sent_; }
146
std::chrono::steady_clock::time_point GetReadyTime()
const
noexcept
{
return
ready_time_; }
147
virtual
void
SendResponse(engine::
io
::
RwBase
& socket) = 0;
148
149
virtual
void
SetStatusServiceUnavailable() = 0;
150
virtual
void
SetStatusOk() = 0;
151
virtual
void
SetStatusNotFound() = 0;
152
153
// HTTP/2.0 only
154
void
SetStreamId(std::int32_t stream_id);
155
std::optional<std::int32_t> GetStreamId()
const
{
return
stream_id_; }
156
void
SetStreamProdicer(
http
::impl::Http2StreamEventProducer&& producer);
157
http
::impl::Http2StreamEventProducer GetStreamProducer();
158
/// @endcond
159
160
protected
:
161
ResponseBase(ResponseDataAccounter& data_account, std::chrono::steady_clock::time_point now);
162
163
void
SetSendFailed();
164
void
SetSent(std::size_t bytes_sent);
165
166
private
:
167
void
StoreData(impl::ChunkStorage data);
168
169
static
constexpr
auto
kUnset = std::chrono::steady_clock::time_point::min();
170
171
ResponseDataAccounter& accounter_;
172
impl::ChunkStorage data_;
173
std::chrono::steady_clock::time_point create_time_;
174
std::chrono::steady_clock::time_point ready_time_{kUnset};
175
std::size_t accounted_size_ = 0;
176
std::size_t bytes_sent_ = 0;
177
bool
is_sent_ =
false
;
178
std::optional<std::int32_t> stream_id_;
179
std::optional<
http
::impl::Http2StreamEventProducer> producer_{};
180
};
181
182
}
// namespace server::request
183
184
USERVER_NAMESPACE_END
userver
server
request
response_base.hpp
Generated on
for userver by
Doxygen
1.17.0