Skip to content

Commit 8b0e68f

Browse files
cindyyan317kuznetsss
authored andcommitted
chore: Add counter for total messages waiting to be sent (#1691)
1 parent 189098d commit 8b0e68f

File tree

4 files changed

+78
-23
lines changed

4 files changed

+78
-23
lines changed

src/util/requests/impl/WsConnectionImpl.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ class WsConnectionImpl : public WsConnection {
134134
// The timer below can be called with no error code even if the operation is completed before the timeout, so we
135135
// need an additional flag here
136136
timer.async_wait([&cancellationSignal, isCompleted](boost::system::error_code errorCode) {
137-
if (!errorCode and not *isCompleted)
137+
if (!errorCode and not*isCompleted)
138138
cancellationSignal.emit(boost::asio::cancellation_type::terminal);
139139
});
140140
operation(cyield);

src/web/Server.hpp

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,8 @@ namespace web {
6969
* @tparam HandlerType The executor to handle the requests
7070
*/
7171
template <
72-
template <typename>
73-
class PlainSessionType,
74-
template <typename>
75-
class SslSessionType,
72+
template <typename> class PlainSessionType,
73+
template <typename> class SslSessionType,
7674
SomeServerHandler HandlerType>
7775
class Detector : public std::enable_shared_from_this<Detector<PlainSessionType, SslSessionType, HandlerType>> {
7876
using std::enable_shared_from_this<Detector<PlainSessionType, SslSessionType, HandlerType>>::shared_from_this;
@@ -191,10 +189,8 @@ class Detector : public std::enable_shared_from_this<Detector<PlainSessionType,
191189
* @tparam HandlerType The handler to process the request and return response.
192190
*/
193191
template <
194-
template <typename>
195-
class PlainSessionType,
196-
template <typename>
197-
class SslSessionType,
192+
template <typename> class PlainSessionType,
193+
template <typename> class SslSessionType,
198194
SomeServerHandler HandlerType>
199195
class Server : public std::enable_shared_from_this<Server<PlainSessionType, SslSessionType, HandlerType>> {
200196
using std::enable_shared_from_this<Server<PlainSessionType, SslSessionType, HandlerType>>::shared_from_this;

src/web/impl/WsBase.hpp

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@
2323
#include "rpc/common/Types.hpp"
2424
#include "util/Taggable.hpp"
2525
#include "util/log/Logger.hpp"
26+
#include "util/prometheus/Gauge.hpp"
27+
#include "util/prometheus/Label.hpp"
28+
#include "util/prometheus/Prometheus.hpp"
2629
#include "web/DOSGuard.hpp"
2730
#include "web/interface/Concepts.hpp"
2831
#include "web/interface/ConnectionBase.hpp"
@@ -71,6 +74,8 @@ template <template <typename> typename Derived, SomeServerHandler HandlerType>
7174
class WsBase : public ConnectionBase, public std::enable_shared_from_this<WsBase<Derived, HandlerType>> {
7275
using std::enable_shared_from_this<WsBase<Derived, HandlerType>>::shared_from_this;
7376

77+
std::reference_wrapper<util::prometheus::GaugeInt> messagesLength_;
78+
7479
boost::beast::flat_buffer buffer_;
7580
std::reference_wrapper<web::DOSGuard> dosGuard_;
7681
bool sending_ = false;
@@ -103,15 +108,26 @@ class WsBase : public ConnectionBase, public std::enable_shared_from_this<WsBase
103108
std::shared_ptr<HandlerType> const& handler,
104109
boost::beast::flat_buffer&& buffer
105110
)
106-
: ConnectionBase(tagFactory, ip), buffer_(std::move(buffer)), dosGuard_(dosGuard), handler_(handler)
111+
: ConnectionBase(tagFactory, ip)
112+
, messagesLength_(PrometheusService::gaugeInt(
113+
"ws_messages_length",
114+
util::prometheus::Labels(),
115+
"The total length of messages in the queue"
116+
))
117+
, buffer_(std::move(buffer))
118+
, dosGuard_(dosGuard)
119+
, handler_(handler)
107120
{
108121
upgraded = true; // NOLINT (cppcoreguidelines-pro-type-member-init)
122+
109123
LOG(perfLog_.debug()) << tag() << "session created";
110124
}
111125

112126
~WsBase() override
113127
{
114128
LOG(perfLog_.debug()) << tag() << "session closed";
129+
if (!messages_.empty())
130+
messagesLength_.get() -= messages_.size();
115131
dosGuard_.get().decrement(clientIp);
116132
}
117133

@@ -135,6 +151,7 @@ class WsBase : public ConnectionBase, public std::enable_shared_from_this<WsBase
135151
onWrite(boost::system::error_code ec, std::size_t)
136152
{
137153
messages_.pop();
154+
--messagesLength_.get();
138155
sending_ = false;
139156
if (ec) {
140157
wsFail(ec, "Failed to write");
@@ -165,6 +182,7 @@ class WsBase : public ConnectionBase, public std::enable_shared_from_this<WsBase
165182
derived().ws().get_executor(),
166183
[this, self = derived().shared_from_this(), msg = std::move(msg)]() {
167184
messages_.push(msg);
185+
++messagesLength_.get();
168186
maybeSendNext();
169187
}
170188
);

tests/unit/web/ServerTests.cpp

Lines changed: 54 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "util/MockPrometheus.hpp"
2323
#include "util/TestHttpSyncClient.hpp"
2424
#include "util/config/Config.hpp"
25+
#include "util/prometheus/Gauge.hpp"
2526
#include "util/prometheus/Label.hpp"
2627
#include "util/prometheus/Prometheus.hpp"
2728
#include "web/DOSGuard.hpp"
@@ -42,6 +43,7 @@
4243
#include <boost/json/parse.hpp>
4344
#include <boost/system/system_error.hpp>
4445
#include <fmt/core.h>
46+
#include <gmock/gmock.h>
4547
#include <gtest/gtest.h>
4648

4749
#include <chrono>
@@ -202,6 +204,8 @@ class WebServerTest : public NoLoggerFixture {
202204
std::optional<std::thread> runner;
203205
};
204206

207+
struct WebServerTestsWithMockPrometheus : WebServerTest, prometheus::WithMockPrometheus {};
208+
205209
class EchoExecutor {
206210
public:
207211
void
@@ -263,16 +267,21 @@ makeServerSync(
263267

264268
} // namespace
265269

266-
TEST_F(WebServerTest, Http)
270+
TEST_F(WebServerTestsWithMockPrometheus, Http)
267271
{
268272
auto e = std::make_shared<EchoExecutor>();
269273
auto const server = makeServerSync(cfg, ctx, std::nullopt, dosGuard, e);
270274
auto const res = HttpSyncClient::syncPost("localhost", port, R"({"Hello":1})");
271275
EXPECT_EQ(res, R"({"Hello":1})");
272276
}
273277

274-
TEST_F(WebServerTest, Ws)
278+
TEST_F(WebServerTestsWithMockPrometheus, Ws)
275279
{
280+
::testing::StrictMock<util::prometheus::MockCounterImplInt>& wsMessagesCounterMock =
281+
makeMock<util::prometheus::GaugeInt>("ws_messages_length", "");
282+
EXPECT_CALL(wsMessagesCounterMock, add(1));
283+
EXPECT_CALL(wsMessagesCounterMock, add(-1));
284+
276285
auto e = std::make_shared<EchoExecutor>();
277286
auto const server = makeServerSync(cfg, ctx, std::nullopt, dosGuard, e);
278287
WebSocketSyncClient wsClient;
@@ -282,7 +291,7 @@ TEST_F(WebServerTest, Ws)
282291
wsClient.disconnect();
283292
}
284293

285-
TEST_F(WebServerTest, HttpInternalError)
294+
TEST_F(WebServerTestsWithMockPrometheus, HttpInternalError)
286295
{
287296
auto e = std::make_shared<ExceptionExecutor>();
288297
auto const server = makeServerSync(cfg, ctx, std::nullopt, dosGuard, e);
@@ -293,8 +302,13 @@ TEST_F(WebServerTest, HttpInternalError)
293302
);
294303
}
295304

296-
TEST_F(WebServerTest, WsInternalError)
305+
TEST_F(WebServerTestsWithMockPrometheus, WsInternalError)
297306
{
307+
::testing::StrictMock<util::prometheus::MockCounterImplInt>& wsMessagesCounterMock =
308+
makeMock<util::prometheus::GaugeInt>("ws_messages_length", "");
309+
EXPECT_CALL(wsMessagesCounterMock, add(1));
310+
EXPECT_CALL(wsMessagesCounterMock, add(-1));
311+
298312
auto e = std::make_shared<ExceptionExecutor>();
299313
auto const server = makeServerSync(cfg, ctx, std::nullopt, dosGuard, e);
300314
WebSocketSyncClient wsClient;
@@ -307,8 +321,13 @@ TEST_F(WebServerTest, WsInternalError)
307321
);
308322
}
309323

310-
TEST_F(WebServerTest, WsInternalErrorNotJson)
324+
TEST_F(WebServerTestsWithMockPrometheus, WsInternalErrorNotJson)
311325
{
326+
::testing::StrictMock<util::prometheus::MockCounterImplInt>& wsMessagesCounterMock =
327+
makeMock<util::prometheus::GaugeInt>("ws_messages_length", "");
328+
EXPECT_CALL(wsMessagesCounterMock, add(1));
329+
EXPECT_CALL(wsMessagesCounterMock, add(-1));
330+
312331
auto e = std::make_shared<ExceptionExecutor>();
313332
auto const server = makeServerSync(cfg, ctx, std::nullopt, dosGuard, e);
314333
WebSocketSyncClient wsClient;
@@ -321,7 +340,7 @@ TEST_F(WebServerTest, WsInternalErrorNotJson)
321340
);
322341
}
323342

324-
TEST_F(WebServerTest, Https)
343+
TEST_F(WebServerTestsWithMockPrometheus, Https)
325344
{
326345
auto e = std::make_shared<EchoExecutor>();
327346
auto sslCtx = parseCertsForTest();
@@ -331,8 +350,13 @@ TEST_F(WebServerTest, Https)
331350
EXPECT_EQ(res, R"({"Hello":1})");
332351
}
333352

334-
TEST_F(WebServerTest, Wss)
353+
TEST_F(WebServerTestsWithMockPrometheus, Wss)
335354
{
355+
::testing::StrictMock<util::prometheus::MockCounterImplInt>& wsMessagesCounterMock =
356+
makeMock<util::prometheus::GaugeInt>("ws_messages_length", "");
357+
EXPECT_CALL(wsMessagesCounterMock, add(1));
358+
EXPECT_CALL(wsMessagesCounterMock, add(-1));
359+
336360
auto e = std::make_shared<EchoExecutor>();
337361
auto sslCtx = parseCertsForTest();
338362
auto const ctxSslRef = sslCtx ? std::optional<std::reference_wrapper<ssl::context>>{sslCtx.value()} : std::nullopt;
@@ -345,7 +369,7 @@ TEST_F(WebServerTest, Wss)
345369
wsClient.disconnect();
346370
}
347371

348-
TEST_F(WebServerTest, HttpRequestOverload)
372+
TEST_F(WebServerTestsWithMockPrometheus, HttpRequestOverload)
349373
{
350374
auto e = std::make_shared<EchoExecutor>();
351375
auto const server = makeServerSync(cfg, ctx, std::nullopt, dosGuardOverload, e);
@@ -358,8 +382,13 @@ TEST_F(WebServerTest, HttpRequestOverload)
358382
);
359383
}
360384

361-
TEST_F(WebServerTest, WsRequestOverload)
385+
TEST_F(WebServerTestsWithMockPrometheus, WsRequestOverload)
362386
{
387+
::testing::StrictMock<util::prometheus::MockCounterImplInt>& wsMessagesCounterMock =
388+
makeMock<util::prometheus::GaugeInt>("ws_messages_length", "");
389+
EXPECT_CALL(wsMessagesCounterMock, add(1)).Times(2);
390+
EXPECT_CALL(wsMessagesCounterMock, add(-1)).Times(2);
391+
363392
auto e = std::make_shared<EchoExecutor>();
364393
auto const server = makeServerSync(cfg, ctx, std::nullopt, dosGuardOverload, e);
365394
WebSocketSyncClient wsClient;
@@ -377,7 +406,7 @@ TEST_F(WebServerTest, WsRequestOverload)
377406
);
378407
}
379408

380-
TEST_F(WebServerTest, HttpPayloadOverload)
409+
TEST_F(WebServerTestsWithMockPrometheus, HttpPayloadOverload)
381410
{
382411
std::string const s100(100, 'a');
383412
auto e = std::make_shared<EchoExecutor>();
@@ -389,8 +418,13 @@ TEST_F(WebServerTest, HttpPayloadOverload)
389418
);
390419
}
391420

392-
TEST_F(WebServerTest, WsPayloadOverload)
421+
TEST_F(WebServerTestsWithMockPrometheus, WsPayloadOverload)
393422
{
423+
::testing::StrictMock<util::prometheus::MockCounterImplInt>& wsMessagesCounterMock =
424+
makeMock<util::prometheus::GaugeInt>("ws_messages_length", "");
425+
EXPECT_CALL(wsMessagesCounterMock, add(1));
426+
EXPECT_CALL(wsMessagesCounterMock, add(-1));
427+
394428
std::string const s100(100, 'a');
395429
auto e = std::make_shared<EchoExecutor>();
396430
auto server = makeServerSync(cfg, ctx, std::nullopt, dosGuardOverload, e);
@@ -404,7 +438,7 @@ TEST_F(WebServerTest, WsPayloadOverload)
404438
);
405439
}
406440

407-
TEST_F(WebServerTest, WsTooManyConnection)
441+
TEST_F(WebServerTestsWithMockPrometheus, WsTooManyConnection)
408442
{
409443
auto e = std::make_shared<EchoExecutor>();
410444
auto server = makeServerSync(cfg, ctx, std::nullopt, dosGuardOverload, e);
@@ -510,10 +544,17 @@ struct WebServerAdminTestParams {
510544
std::string expectedResponse;
511545
};
512546

513-
class WebServerAdminTest : public WebServerTest, public ::testing::WithParamInterface<WebServerAdminTestParams> {};
547+
class WebServerAdminTest : public WebServerTest,
548+
public ::testing::WithParamInterface<WebServerAdminTestParams>,
549+
public prometheus::WithMockPrometheus {};
514550

515551
TEST_P(WebServerAdminTest, WsAdminCheck)
516552
{
553+
::testing::StrictMock<util::prometheus::MockCounterImplInt>& wsMessagesCounterMock =
554+
makeMock<util::prometheus::GaugeInt>("ws_messages_length", "");
555+
EXPECT_CALL(wsMessagesCounterMock, add(1));
556+
EXPECT_CALL(wsMessagesCounterMock, add(-1));
557+
517558
auto e = std::make_shared<AdminCheckExecutor>();
518559
Config const serverConfig{parse(GetParam().config)};
519560
auto server = makeServerSync(serverConfig, ctx, std::nullopt, dosGuardOverload, e);

0 commit comments

Comments
 (0)