Skip to content

Commit

Permalink
chore: Add counter for total messages waiting to be sent (#1691)
Browse files Browse the repository at this point in the history
  • Loading branch information
cindyyan317 authored Oct 16, 2024
1 parent a210117 commit 9b0b4f5
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 16 deletions.
21 changes: 20 additions & 1 deletion src/web/impl/WsBase.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
#include "rpc/common/Types.hpp"
#include "util/Taggable.hpp"
#include "util/log/Logger.hpp"
#include "util/prometheus/Gauge.hpp"
#include "util/prometheus/Label.hpp"
#include "util/prometheus/Prometheus.hpp"
#include "web/dosguard/DOSGuardInterface.hpp"
#include "web/interface/Concepts.hpp"
#include "web/interface/ConnectionBase.hpp"
Expand Down Expand Up @@ -71,6 +74,8 @@ template <template <typename> typename Derived, SomeServerHandler HandlerType>
class WsBase : public ConnectionBase, public std::enable_shared_from_this<WsBase<Derived, HandlerType>> {
using std::enable_shared_from_this<WsBase<Derived, HandlerType>>::shared_from_this;

std::reference_wrapper<util::prometheus::GaugeInt> messagesLength_;

boost::beast::flat_buffer buffer_;
std::reference_wrapper<dosguard::DOSGuardInterface> dosGuard_;
bool sending_ = false;
Expand Down Expand Up @@ -103,15 +108,26 @@ class WsBase : public ConnectionBase, public std::enable_shared_from_this<WsBase
std::shared_ptr<HandlerType> const& handler,
boost::beast::flat_buffer&& buffer
)
: ConnectionBase(tagFactory, ip), buffer_(std::move(buffer)), dosGuard_(dosGuard), handler_(handler)
: ConnectionBase(tagFactory, ip)
, messagesLength_(PrometheusService::gaugeInt(
"ws_messages_length",
util::prometheus::Labels(),
"The total length of messages in the queue"
))
, buffer_(std::move(buffer))
, dosGuard_(dosGuard)
, handler_(handler)
{
upgraded = true; // NOLINT (cppcoreguidelines-pro-type-member-init)

LOG(perfLog_.debug()) << tag() << "session created";
}

~WsBase() override
{
LOG(perfLog_.debug()) << tag() << "session closed";
if (!messages_.empty())
messagesLength_.get() -= messages_.size();
dosGuard_.get().decrement(clientIp);
}

Expand All @@ -134,7 +150,9 @@ class WsBase : public ConnectionBase, public std::enable_shared_from_this<WsBase
void
onWrite(boost::system::error_code ec, std::size_t)
{
LOG(perfLog_.info()) << tag() << "xinmeng sent message";
messages_.pop();
--messagesLength_.get();
sending_ = false;
if (ec) {
wsFail(ec, "Failed to write");
Expand Down Expand Up @@ -165,6 +183,7 @@ class WsBase : public ConnectionBase, public std::enable_shared_from_this<WsBase
derived().ws().get_executor(),
[this, self = derived().shared_from_this(), msg = std::move(msg)]() {
messages_.push(msg);
++messagesLength_.get();
maybeSendNext();
}
);
Expand Down
71 changes: 56 additions & 15 deletions tests/unit/web/ServerTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "util/MockPrometheus.hpp"
#include "util/TestHttpSyncClient.hpp"
#include "util/config/Config.hpp"
#include "util/prometheus/Gauge.hpp"
#include "util/prometheus/Label.hpp"
#include "util/prometheus/Prometheus.hpp"
#include "web/Server.hpp"
Expand All @@ -42,6 +43,7 @@
#include <boost/json/value.hpp>
#include <boost/system/system_error.hpp>
#include <fmt/core.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include <condition_variable>
Expand Down Expand Up @@ -144,6 +146,8 @@ struct WebServerTest : NoLoggerFixture {
std::optional<std::thread> runner;
};

struct WebServerTestsWithMockPrometheus : WebServerTest, prometheus::WithMockPrometheus {};

class EchoExecutor {
public:
void
Expand Down Expand Up @@ -204,16 +208,21 @@ makeServerSync(

} // namespace

TEST_F(WebServerTest, Http)
TEST_F(WebServerTestsWithMockPrometheus, Http)
{
auto e = std::make_shared<EchoExecutor>();
auto const server = makeServerSync(cfg, ctx, dosGuard, e);
auto const res = HttpSyncClient::syncPost("localhost", port, R"({"Hello":1})");
EXPECT_EQ(res, R"({"Hello":1})");
}

TEST_F(WebServerTest, Ws)
TEST_F(WebServerTestsWithMockPrometheus, Ws)
{
::testing::StrictMock<util::prometheus::MockCounterImplInt>& wsMessagesCounterMock =
makeMock<util::prometheus::GaugeInt>("ws_messages_length", "");
EXPECT_CALL(wsMessagesCounterMock, add(1));
EXPECT_CALL(wsMessagesCounterMock, add(-1));

auto e = std::make_shared<EchoExecutor>();
auto const server = makeServerSync(cfg, ctx, dosGuard, e);
WebSocketSyncClient wsClient;
Expand All @@ -223,7 +232,7 @@ TEST_F(WebServerTest, Ws)
wsClient.disconnect();
}

TEST_F(WebServerTest, HttpInternalError)
TEST_F(WebServerTestsWithMockPrometheus, HttpInternalError)
{
auto e = std::make_shared<ExceptionExecutor>();
auto const server = makeServerSync(cfg, ctx, dosGuard, e);
Expand All @@ -234,8 +243,13 @@ TEST_F(WebServerTest, HttpInternalError)
);
}

TEST_F(WebServerTest, WsInternalError)
TEST_F(WebServerTestsWithMockPrometheus, WsInternalError)
{
::testing::StrictMock<util::prometheus::MockCounterImplInt>& wsMessagesCounterMock =
makeMock<util::prometheus::GaugeInt>("ws_messages_length", "");
EXPECT_CALL(wsMessagesCounterMock, add(1));
EXPECT_CALL(wsMessagesCounterMock, add(-1));

auto e = std::make_shared<ExceptionExecutor>();
auto const server = makeServerSync(cfg, ctx, dosGuard, e);
WebSocketSyncClient wsClient;
Expand All @@ -248,8 +262,13 @@ TEST_F(WebServerTest, WsInternalError)
);
}

TEST_F(WebServerTest, WsInternalErrorNotJson)
TEST_F(WebServerTestsWithMockPrometheus, WsInternalErrorNotJson)
{
::testing::StrictMock<util::prometheus::MockCounterImplInt>& wsMessagesCounterMock =
makeMock<util::prometheus::GaugeInt>("ws_messages_length", "");
EXPECT_CALL(wsMessagesCounterMock, add(1));
EXPECT_CALL(wsMessagesCounterMock, add(-1));

auto e = std::make_shared<ExceptionExecutor>();
auto const server = makeServerSync(cfg, ctx, dosGuard, e);
WebSocketSyncClient wsClient;
Expand All @@ -262,7 +281,7 @@ TEST_F(WebServerTest, WsInternalErrorNotJson)
);
}

TEST_F(WebServerTest, IncompleteSslConfig)
TEST_F(WebServerTestsWithMockPrometheus, IncompleteSslConfig)
{
auto e = std::make_shared<EchoExecutor>();

Expand All @@ -273,7 +292,7 @@ TEST_F(WebServerTest, IncompleteSslConfig)
EXPECT_EQ(server, nullptr);
}

TEST_F(WebServerTest, WrongSslConfig)
TEST_F(WebServerTestsWithMockPrometheus, WrongSslConfig)
{
auto e = std::make_shared<EchoExecutor>();

Expand All @@ -285,7 +304,7 @@ TEST_F(WebServerTest, WrongSslConfig)
EXPECT_EQ(server, nullptr);
}

TEST_F(WebServerTest, Https)
TEST_F(WebServerTestsWithMockPrometheus, Https)
{
auto e = std::make_shared<EchoExecutor>();
cfg = Config{addSslConfig(generateJSONWithDynamicPort(port))};
Expand All @@ -294,8 +313,13 @@ TEST_F(WebServerTest, Https)
EXPECT_EQ(res, R"({"Hello":1})");
}

TEST_F(WebServerTest, Wss)
TEST_F(WebServerTestsWithMockPrometheus, Wss)
{
::testing::StrictMock<util::prometheus::MockCounterImplInt>& wsMessagesCounterMock =
makeMock<util::prometheus::GaugeInt>("ws_messages_length", "");
EXPECT_CALL(wsMessagesCounterMock, add(1));
EXPECT_CALL(wsMessagesCounterMock, add(-1));

auto e = std::make_shared<EchoExecutor>();
cfg = Config{addSslConfig(generateJSONWithDynamicPort(port))};
auto server = makeServerSync(cfg, ctx, dosGuard, e);
Expand All @@ -306,7 +330,7 @@ TEST_F(WebServerTest, Wss)
wsClient.disconnect();
}

TEST_F(WebServerTest, HttpRequestOverload)
TEST_F(WebServerTestsWithMockPrometheus, HttpRequestOverload)
{
auto e = std::make_shared<EchoExecutor>();
auto const server = makeServerSync(cfg, ctx, dosGuardOverload, e);
Expand All @@ -319,8 +343,13 @@ TEST_F(WebServerTest, HttpRequestOverload)
);
}

TEST_F(WebServerTest, WsRequestOverload)
TEST_F(WebServerTestsWithMockPrometheus, WsRequestOverload)
{
::testing::StrictMock<util::prometheus::MockCounterImplInt>& wsMessagesCounterMock =
makeMock<util::prometheus::GaugeInt>("ws_messages_length", "");
EXPECT_CALL(wsMessagesCounterMock, add(1)).Times(2);
EXPECT_CALL(wsMessagesCounterMock, add(-1)).Times(2);

auto e = std::make_shared<EchoExecutor>();
auto const server = makeServerSync(cfg, ctx, dosGuardOverload, e);
WebSocketSyncClient wsClient;
Expand All @@ -338,7 +367,7 @@ TEST_F(WebServerTest, WsRequestOverload)
);
}

TEST_F(WebServerTest, HttpPayloadOverload)
TEST_F(WebServerTestsWithMockPrometheus, HttpPayloadOverload)
{
std::string const s100(100, 'a');
auto e = std::make_shared<EchoExecutor>();
Expand All @@ -350,8 +379,13 @@ TEST_F(WebServerTest, HttpPayloadOverload)
);
}

TEST_F(WebServerTest, WsPayloadOverload)
TEST_F(WebServerTestsWithMockPrometheus, WsPayloadOverload)
{
::testing::StrictMock<util::prometheus::MockCounterImplInt>& wsMessagesCounterMock =
makeMock<util::prometheus::GaugeInt>("ws_messages_length", "");
EXPECT_CALL(wsMessagesCounterMock, add(1));
EXPECT_CALL(wsMessagesCounterMock, add(-1));

std::string const s100(100, 'a');
auto e = std::make_shared<EchoExecutor>();
auto server = makeServerSync(cfg, ctx, dosGuardOverload, e);
Expand All @@ -365,7 +399,7 @@ TEST_F(WebServerTest, WsPayloadOverload)
);
}

TEST_F(WebServerTest, WsTooManyConnection)
TEST_F(WebServerTestsWithMockPrometheus, WsTooManyConnection)
{
auto e = std::make_shared<EchoExecutor>();
auto server = makeServerSync(cfg, ctx, dosGuardOverload, e);
Expand Down Expand Up @@ -471,10 +505,17 @@ struct WebServerAdminTestParams {
std::string expectedResponse;
};

class WebServerAdminTest : public WebServerTest, public ::testing::WithParamInterface<WebServerAdminTestParams> {};
class WebServerAdminTest : public WebServerTest,
public ::testing::WithParamInterface<WebServerAdminTestParams>,
public prometheus::WithMockPrometheus {};

TEST_P(WebServerAdminTest, WsAdminCheck)
{
::testing::StrictMock<util::prometheus::MockCounterImplInt>& wsMessagesCounterMock =
makeMock<util::prometheus::GaugeInt>("ws_messages_length", "");
EXPECT_CALL(wsMessagesCounterMock, add(1));
EXPECT_CALL(wsMessagesCounterMock, add(-1));

auto e = std::make_shared<AdminCheckExecutor>();
Config const serverConfig{boost::json::parse(GetParam().config)};
auto server = makeServerSync(serverConfig, ctx, dosGuardOverload, e);
Expand Down

0 comments on commit 9b0b4f5

Please sign in to comment.