xrpld
Toggle main menu visibility
Loading...
Searching...
No Matches
include
xrpl
beast
asio
io_latency_probe.h
1
#pragma once
2
3
#include <xrpl/beast/utility/instrumentation.h>
4
5
#include <boost/asio/basic_waitable_timer.hpp>
6
#include <boost/asio/io_context.hpp>
7
#include <boost/asio/post.hpp>
8
9
#include <
chrono
>
10
#include <
condition_variable
>
11
#include <
cstddef
>
12
#include <
mutex
>
13
#include <
stdexcept
>
14
15
namespace
beast
{
16
20
template
<
class
Clock>
21
class
IOLatencyProbe
22
{
23
private
:
24
using
duration
= Clock::duration;
25
using
time_point
= Clock::time_point;
26
27
std::recursive_mutex
mutex_
;
28
std::condition_variable_any
cond_
;
29
std::size_t
count_
{1};
30
duration
const
period_
;
31
boost::asio::io_context&
ios_
;
32
boost::asio::basic_waitable_timer<std::chrono::steady_clock>
timer_
;
33
bool
cancel_
{
false
};
34
35
public
:
36
IOLatencyProbe
(
duration
const
& period, boost::asio::io_context& ios)
37
:
period_
(period),
ios_
(ios),
timer_
(
ios_
)
38
{
39
}
40
41
~IOLatencyProbe
()
42
{
43
std::unique_lock
<
decltype
(
mutex_
)> lock(
mutex_
);
44
cancel
(lock,
true
);
45
}
46
51
boost::asio::io_context&
52
getIoContext
()
53
{
54
return
ios_
;
55
}
56
57
[[nodiscard]] boost::asio::io_context
const
&
58
getIoContext
()
const
59
{
60
return
ios_
;
61
}
62
63
69
void
70
cancel
()
71
{
72
std::unique_lock
<
decltype
(
mutex_
)> lock(
mutex_
);
73
cancel
(lock,
true
);
74
}
75
76
void
77
cancelAsync
()
78
{
79
std::unique_lock
<
decltype
(
mutex_
)> lock(
mutex_
);
80
cancel
(lock,
false
);
81
}
82
83
89
template
<
class
Handler>
90
void
91
sampleOne
(Handler&& handler)
92
{
93
std::scoped_lock
const
lock(
mutex_
);
94
if
(
cancel_
)
95
throw
std::logic_error
(
"IOLatencyProbe is canceled"
);
96
boost::asio::post(
97
ios_
,
SampleOp<Handler>
(
std::forward<Handler>
(handler), Clock::now(),
false
,
this
));
98
}
99
105
template
<
class
Handler>
106
void
107
sample
(Handler&& handler)
108
{
109
std::scoped_lock
const
lock(
mutex_
);
110
if
(
cancel_
)
111
throw
std::logic_error
(
"IOLatencyProbe is canceled"
);
112
boost::asio::post(
113
ios_
,
SampleOp<Handler>
(
std::forward<Handler>
(handler), Clock::now(),
true
,
this
));
114
}
115
116
private
:
117
void
118
cancel
(
std::unique_lock
<
decltype
(
mutex_
)>& lock,
bool
wait)
119
{
120
if
(!
cancel_
)
121
{
122
--
count_
;
123
cancel_
=
true
;
124
}
125
126
if
(wait)
127
cond_
.wait(lock, [
this
] {
return
this->count_ == 0; });
128
}
129
130
void
131
addref
()
132
{
133
std::scoped_lock
const
lock(
mutex_
);
134
++
count_
;
135
}
136
137
void
138
release
()
139
{
140
std::scoped_lock
const
lock(
mutex_
);
141
if
(--
count_
== 0)
142
cond_
.notify_all();
143
}
144
145
template
<
class
Handler>
146
struct
SampleOp
147
{
148
Handler
handler
;
149
time_point
start
;
150
bool
repeat
;
151
IOLatencyProbe
*
probe
;
152
153
SampleOp
(
154
Handler
const
&
handler
,
155
time_point
const
&
start
,
156
bool
repeat
,
157
IOLatencyProbe
*
probe
)
158
:
handler
(
handler
),
start
(
start
),
repeat
(
repeat
),
probe
(
probe
)
159
{
160
XRPL_ASSERT(
161
probe
,
162
"beast::IOLatencyProbe::SampleOp::SampleOp : non-null "
163
"probe input"
);
164
probe
->addref();
165
}
166
167
SampleOp
(
SampleOp
&& from) noexcept
168
:
handler
(std::move(from.handler))
169
,
start
(from.start)
170
,
repeat
(from.repeat)
171
,
probe
(from.probe)
172
{
173
XRPL_ASSERT(
174
probe
,
175
"beast::IOLatencyProbe::SampleOp::SampleOp(SampleOp&&) : "
176
"non-null probe input"
);
177
from.probe =
nullptr
;
178
}
179
180
SampleOp
(
SampleOp
const
&) =
delete
;
181
SampleOp
182
operator=
(
SampleOp
const
&) =
delete
;
183
SampleOp
&
184
operator=
(
SampleOp
&&) =
delete
;
185
186
~SampleOp
()
187
{
188
if
(
probe
)
189
probe
->release();
190
}
191
192
void
193
operator()
()
const
194
{
195
if
(
probe
==
nullptr
)
196
return
;
197
typename
Clock::time_point
const
now(Clock::now());
198
typename
Clock::duration
const
elapsed(now -
start
);
199
200
handler
(elapsed);
201
202
{
203
std::scoped_lock
const
lock(
probe
->mutex_);
204
if
(
probe
->cancel_)
205
return
;
206
}
207
208
if
(
repeat
)
209
{
210
// Calculate when we want to sample again, and
211
// adjust for the expected latency.
212
//
213
typename
Clock::time_point
const
when(now +
probe
->period_ - (2 * elapsed));
214
215
if
(when <= now)
216
{
217
// The latency is too high to maintain the desired
218
// period so don't bother with a timer.
219
//
220
boost::asio::post(
probe
->ios_,
SampleOp<Handler>
(
handler
, now,
repeat
,
probe
));
221
}
222
else
223
{
224
probe
->timer_.expires_after(when - now);
225
probe
->timer_.async_wait(
SampleOp<Handler>
(
handler
, now,
repeat
,
probe
));
226
}
227
}
228
}
229
230
void
231
operator()
(boost::system::error_code
const
& ec)
232
{
233
if
(
probe
==
nullptr
)
234
return
;
235
typename
Clock::time_point
const
now(Clock::now());
236
boost::asio::post(
probe
->ios_,
SampleOp<Handler>
(
handler
, now,
repeat
,
probe
));
237
}
238
};
239
};
240
241
}
// namespace beast
chrono
beast::IOLatencyProbe::IOLatencyProbe
IOLatencyProbe(duration const &period, boost::asio::io_context &ios)
Definition
io_latency_probe.h:36
beast::IOLatencyProbe::count_
std::size_t count_
Definition
io_latency_probe.h:29
beast::IOLatencyProbe::getIoContext
boost::asio::io_context const & getIoContext() const
Definition
io_latency_probe.h:58
beast::IOLatencyProbe::mutex_
std::recursive_mutex mutex_
Definition
io_latency_probe.h:27
beast::IOLatencyProbe::getIoContext
boost::asio::io_context & getIoContext()
Return the io_context associated with the latency probe.
Definition
io_latency_probe.h:52
beast::IOLatencyProbe::~IOLatencyProbe
~IOLatencyProbe()
Definition
io_latency_probe.h:41
beast::IOLatencyProbe::sampleOne
void sampleOne(Handler &&handler)
Measure one sample of i/o latency.
Definition
io_latency_probe.h:91
beast::IOLatencyProbe::cancel
void cancel(std::unique_lock< decltype(mutex_)> &lock, bool wait)
Definition
io_latency_probe.h:118
beast::IOLatencyProbe::cond_
std::condition_variable_any cond_
Definition
io_latency_probe.h:28
beast::IOLatencyProbe::cancelAsync
void cancelAsync()
Definition
io_latency_probe.h:77
beast::IOLatencyProbe::period_
duration const period_
Definition
io_latency_probe.h:30
beast::IOLatencyProbe::cancel
void cancel()
Cancel all pending i/o.
Definition
io_latency_probe.h:70
beast::IOLatencyProbe::release
void release()
Definition
io_latency_probe.h:138
beast::IOLatencyProbe::cancel_
bool cancel_
Definition
io_latency_probe.h:33
beast::IOLatencyProbe::addref
void addref()
Definition
io_latency_probe.h:131
beast::IOLatencyProbe::sample
void sample(Handler &&handler)
Initiate continuous i/o latency sampling.
Definition
io_latency_probe.h:107
beast::IOLatencyProbe::timer_
boost::asio::basic_waitable_timer< std::chrono::steady_clock > timer_
Definition
io_latency_probe.h:32
beast::IOLatencyProbe::duration
Clock::duration duration
Definition
io_latency_probe.h:24
beast::IOLatencyProbe::ios_
boost::asio::io_context & ios_
Definition
io_latency_probe.h:31
beast::IOLatencyProbe::time_point
Clock::time_point time_point
Definition
io_latency_probe.h:25
std::condition_variable_any
condition_variable
cstddef
std::forward
T forward(T... args)
std::logic_error
mutex
beast
Definition
base_uint.h:697
std::recursive_mutex
std::scoped_lock
std::size_t
stdexcept
beast::IOLatencyProbe::SampleOp
Definition
io_latency_probe.h:147
beast::IOLatencyProbe::SampleOp::operator()
void operator()(boost::system::error_code const &ec)
Definition
io_latency_probe.h:231
beast::IOLatencyProbe::SampleOp::operator=
SampleOp operator=(SampleOp const &)=delete
beast::IOLatencyProbe::SampleOp::~SampleOp
~SampleOp()
Definition
io_latency_probe.h:186
beast::IOLatencyProbe::SampleOp::operator()
void operator()() const
Definition
io_latency_probe.h:193
beast::IOLatencyProbe::SampleOp::SampleOp
SampleOp(SampleOp const &)=delete
beast::IOLatencyProbe::SampleOp::repeat
bool repeat
Definition
io_latency_probe.h:150
beast::IOLatencyProbe::SampleOp::probe
IOLatencyProbe * probe
Definition
io_latency_probe.h:151
beast::IOLatencyProbe::SampleOp::operator=
SampleOp & operator=(SampleOp &&)=delete
beast::IOLatencyProbe::SampleOp::handler
Handler handler
Definition
io_latency_probe.h:148
beast::IOLatencyProbe::SampleOp::SampleOp
SampleOp(SampleOp &&from) noexcept
Definition
io_latency_probe.h:167
beast::IOLatencyProbe::SampleOp::start
time_point start
Definition
io_latency_probe.h:149
beast::IOLatencyProbe::SampleOp::SampleOp
SampleOp(Handler const &handler, time_point const &start, bool repeat, IOLatencyProbe *probe)
Definition
io_latency_probe.h:153
std::unique_lock
Generated by
1.17.0