Skip to content

Commit 0b72b96

Browse files
Sven Göthelcaolanm
Sven Göthel
authored andcommitted
cool#9833: Adding net::Defaults to UT limited connections
Using runtime mutable defaults for network properties allows us to test the connection limitation code. Costs are removal of constexpr properties, using a global instance, hence rendering the code less optimized and more pessimistic. Signed-off-by: Sven Göthel <[email protected]> Change-Id: I5172b4067598c02678dd0cd2f56c0574013623d1
1 parent 61f7391 commit 0b72b96

9 files changed

+60
-47
lines changed

common/Unit.hpp

-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77

88
#pragma once
99

10-
#include <atomic>
1110
#include <cassert>
1211
#include <chrono>
1312
#include <map>

net/NetUtil.hpp

+16
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#pragma once
1313

14+
#include <chrono>
1415
#include <functional>
1516
#include <string>
1617
#include <memory>
@@ -28,6 +29,21 @@ struct sockaddr;
2829
namespace net
2930
{
3031

32+
class DefaultValues
33+
{
34+
public:
35+
/// StreamSocket inactivity timeout in us (3600s default). Zero disables instrument.
36+
std::chrono::microseconds inactivityTimeout;
37+
/// WebSocketHandler average ping timeout in us (12s default). Zero disables instrument.
38+
std::chrono::microseconds wsPingAvgTimeout;
39+
/// WebSocketHandler ping interval in us (18s default), i.e. duration until next ping. Zero disables instrument.
40+
std::chrono::microseconds wsPingInterval;
41+
42+
/// Maximum number of concurrent TCP connections. Zero disables instrument.
43+
size_t maxTCPConnections;
44+
};
45+
extern DefaultValues Defaults;
46+
3147
class HostEntry
3248
{
3349
std::string _requestName;

net/Socket.cpp

+11-5
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@
6060
// Bug in pre C++17 where static constexpr must be defined. Fixed in C++17.
6161
constexpr std::chrono::microseconds SocketPoll::DefaultPollTimeoutMicroS;
6262
constexpr std::chrono::microseconds WebSocketHandler::InitialPingDelayMicroS;
63-
constexpr std::chrono::microseconds WebSocketHandler::PingFrequencyMicroS;
6463

6564
std::atomic<bool> SocketPoll::InhibitThreadChecks(false);
6665
std::atomic<bool> Socket::InhibitThreadChecks(false);
@@ -70,6 +69,11 @@ std::unique_ptr<Watchdog> SocketPoll::PollWatchdog;
7069
std::mutex SocketPoll::StatsMutex;
7170
std::atomic<size_t> SocketPoll::StatsConnectionCount(0);
7271

72+
net::DefaultValues net::Defaults = { .inactivityTimeout = std::chrono::seconds(3600),
73+
.wsPingAvgTimeout = std::chrono::seconds(12),
74+
.wsPingInterval = std::chrono::seconds(18),
75+
.maxTCPConnections = 200000 /* arbitrary value to be resolved */ };
76+
7377
size_t SocketPoll::StatsConnectionMod(size_t added, size_t removed) {
7478
if( added == 0 && removed == 0 ) {
7579
return GetStatsConnectionCount();
@@ -316,6 +320,8 @@ namespace {
316320

317321
SocketPoll::SocketPoll(std::string threadName)
318322
: _name(std::move(threadName)),
323+
_limitedConnections( false ),
324+
_connectionLimit( 0 ),
319325
_pollStartIndex(0),
320326
_stop(false),
321327
_threadStarted(0),
@@ -1488,10 +1494,10 @@ bool StreamSocket::checkRemoval(std::chrono::steady_clock::time_point now)
14881494
// Forced removal on outside-facing IPv[46] network connections only
14891495
const auto durLast =
14901496
std::chrono::duration_cast<std::chrono::milliseconds>(now - getLastSeenTime());
1491-
/// TO Criteria: Violate maximum idle (DefaultInactivityimeoutMicroS default 3600s)
1492-
const bool isInactive = SocketPoll::DefaultInactivityimeoutMicroS > std::chrono::microseconds::zero() &&
1493-
durLast > SocketPoll::DefaultInactivityimeoutMicroS;
1494-
/// TO Criteria: Shall terminate?
1497+
/// Timeout criteria: Violate maximum inactivity (default 3600s)
1498+
const bool isInactive = net::Defaults.inactivityTimeout > std::chrono::microseconds::zero() &&
1499+
durLast > net::Defaults.inactivityTimeout;
1500+
/// Timeout criteria: Shall terminate?
14951501
const bool isTermination = SigUtil::getTerminationFlag();
14961502
if (isInactive || isTermination )
14971503
{

net/Socket.hpp

-2
Original file line numberDiff line numberDiff line change
@@ -715,8 +715,6 @@ class SocketPoll
715715

716716
/// Default poll time - useful to increase for debugging.
717717
static constexpr std::chrono::microseconds DefaultPollTimeoutMicroS = std::chrono::seconds(64);
718-
static constexpr std::chrono::microseconds DefaultInactivityimeoutMicroS = std::chrono::seconds(3600);
719-
static constexpr size_t DefaultMaxTCPConnections = 200000; // arbitrary value to be resolved
720718
static std::atomic<bool> InhibitThreadChecks;
721719

722720
/// Stop the polling thread.

net/WebSocketHandler.hpp

+7-10
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313

1414
#include "NetUtil.hpp"
1515
#include "Socket.hpp"
16-
#include "common/Common.hpp"
1716
#include "common/Log.hpp"
1817
#include "common/Protocol.hpp"
1918
#include "common/Unit.hpp"
@@ -62,8 +61,6 @@ class WebSocketHandler : public ProtocolHandlerInterface
6261
};
6362

6463
static constexpr std::chrono::microseconds InitialPingDelayMicroS = std::chrono::milliseconds(25);
65-
static constexpr std::chrono::microseconds PingFrequencyMicroS = std::chrono::seconds(18);
66-
static constexpr std::chrono::microseconds PingTimeoutMicroS = std::chrono::seconds(12);
6764

6865
public:
6966
/// Perform upgrade ourselves, or select a client web socket.
@@ -75,7 +72,7 @@ class WebSocketHandler : public ProtocolHandlerInterface
7572
:
7673
#if !MOBILEAPP
7774
_lastPingSentTime(std::chrono::steady_clock::now() -
78-
PingFrequencyMicroS +
75+
net::Defaults.wsPingInterval +
7976
std::chrono::microseconds(InitialPingDelayMicroS))
8077
, _isMasking(isClient && isMasking)
8178
, _inFragmentBlock(false)
@@ -603,7 +600,7 @@ class WebSocketHandler : public ProtocolHandlerInterface
603600
const auto timeSincePingMicroS
604601
= std::chrono::duration_cast<std::chrono::microseconds>(now - _lastPingSentTime);
605602
timeoutMaxMicroS
606-
= std::min(timeoutMaxMicroS, (int64_t)(PingFrequencyMicroS - timeSincePingMicroS).count());
603+
= std::min(timeoutMaxMicroS, (int64_t)(net::Defaults.wsPingInterval - timeSincePingMicroS).count());
607604
}
608605
#endif
609606
int events = POLLIN;
@@ -670,21 +667,21 @@ class WebSocketHandler : public ProtocolHandlerInterface
670667
if (_isClient)
671668
return false;
672669

673-
if (PingTimeoutMicroS.count() > std::numeric_limits<double>::epsilon() &&
674-
_pingMicroS.average() >= PingTimeoutMicroS.count())
670+
if (net::Defaults.wsPingAvgTimeout > std::chrono::microseconds::zero() &&
671+
_pingMicroS.average() >= net::Defaults.wsPingAvgTimeout.count())
675672
{
676673
std::shared_ptr<StreamSocket> socket = _socket.lock();
677674
if (socket && socket->isIPType()) // Exclude non-IP local sockets
678675
{
679676
LOG_WRN("CheckTimeout: Timeout websocket: Ping: last " << _pingMicroS.last() << "us, avg "
680-
<< _pingMicroS.average() << "us >= " << PingTimeoutMicroS.count() << "us over "
677+
<< _pingMicroS.average() << "us >= " << net::Defaults.wsPingAvgTimeout.count() << "us over "
681678
<< (int)_pingMicroS.duration() << "s, " << *socket);
682679
shutdownSilent(socket);
683680
return true;
684681
}
685682
}
686-
if (!_pingMicroS.initialized() || (PingFrequencyMicroS > std::chrono::microseconds::zero() &&
687-
now - _pingMicroS.lastTime() >= PingFrequencyMicroS))
683+
if (!_pingMicroS.initialized() || (net::Defaults.wsPingInterval > std::chrono::microseconds::zero() &&
684+
now - _pingMicroS.lastTime() >= net::Defaults.wsPingInterval))
688685
{
689686
const std::shared_ptr<StreamSocket> socket = _socket.lock();
690687
if (socket)

test/UnitTimeoutConnections.cpp

+11-16
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,7 @@ class UnitTimeoutConnections : public UnitTimeoutBase1
3434
{
3535
void configure(Poco::Util::LayeredConfiguration& /* config */) override
3636
{
37-
// to be resolved!
38-
// defaults.MaxConnections = ConnectionLimit;
37+
net::Defaults.maxTCPConnections = ConnectionLimit;
3938
}
4039

4140
public:
@@ -49,24 +48,20 @@ class UnitTimeoutConnections : public UnitTimeoutBase1
4948

5049
void UnitTimeoutConnections::invokeWSDTest()
5150
{
52-
// to be resolved!
53-
if( false )
54-
{
55-
UnitBase::TestResult result = TestResult::Ok;
51+
UnitBase::TestResult result = TestResult::Ok;
5652

57-
result = testHttp(ConnectionLimit, ConnectionCount);
58-
if (result != TestResult::Ok)
59-
exitTest(result);
53+
result = testHttp(ConnectionLimit, ConnectionCount);
54+
if (result != TestResult::Ok)
55+
exitTest(result);
6056

61-
result = testWSPing(ConnectionLimit, ConnectionCount);
62-
if (result != TestResult::Ok)
63-
exitTest(result);
57+
result = testWSPing(ConnectionLimit, ConnectionCount);
58+
if (result != TestResult::Ok)
59+
exitTest(result);
6460

65-
result = testWSDChatPing(ConnectionLimit, ConnectionCount);
66-
if (result != TestResult::Ok)
67-
exitTest(result);
61+
result = testWSDChatPing(ConnectionLimit, ConnectionCount);
62+
if (result != TestResult::Ok)
63+
exitTest(result);
6864

69-
}
7065
exitTest(TestResult::Ok);
7166
}
7267

test/UnitTimeoutWSPing.cpp

+7-11
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,8 @@ class UnitTimeoutWSPing : public UnitTimeoutBase0
3434

3535
void configure(Poco::Util::LayeredConfiguration& /* config */) override
3636
{
37-
// to be resolved!
38-
// defaults.WSPingTimeout = std::chrono::microseconds(20);
39-
// defaults.WSPingPeriod = std::chrono::microseconds(10000);
37+
net::Defaults.wsPingAvgTimeout = std::chrono::microseconds(20);
38+
net::Defaults.wsPingInterval = std::chrono::milliseconds(10);
4039
}
4140

4241
public:
@@ -82,15 +81,12 @@ UnitBase::TestResult UnitTimeoutWSPing::testWSPing()
8281

8382
void UnitTimeoutWSPing::invokeWSDTest()
8483
{
85-
// to be resolved!
86-
if( false )
87-
{
88-
UnitBase::TestResult result = TestResult::Ok;
84+
UnitBase::TestResult result;
85+
86+
result = testWSPing();
87+
if (result != TestResult::Ok)
88+
exitTest(result);
8989

90-
result = testWSPing();
91-
if (result != TestResult::Ok)
92-
exitTest(result);
93-
}
9490
exitTest(TestResult::Ok);
9591
}
9692

wsd/COOLWSD.cpp

+7-1
Original file line numberDiff line numberDiff line change
@@ -2758,6 +2758,12 @@ void COOLWSD::innerInitialize(Poco::Util::Application& self)
27582758
COOLWSD::MaxDocuments = MAX_DOCUMENTS;
27592759
}
27602760
#endif
2761+
{
2762+
LOG_DBG("net::Defaults: WSPing[timeout "
2763+
<< net::Defaults.wsPingAvgTimeout << ", interval " << net::Defaults.wsPingInterval
2764+
<< "], Socket[inactivityTimeout " << net::Defaults.inactivityTimeout
2765+
<< ", maxTCPConnections " << net::Defaults.maxTCPConnections << "]");
2766+
}
27612767

27622768
#if !MOBILEAPP
27632769
NoSeccomp = Util::isKitInProcess() || !getConfigValue<bool>(conf, "security.seccomp", true);
@@ -2929,7 +2935,7 @@ void COOLWSD::innerInitialize(Poco::Util::Application& self)
29292935
#endif
29302936

29312937
WebServerPoll = std::make_unique<TerminatingPoll>("websrv_poll");
2932-
WebServerPoll->setLimiter( SocketPoll::DefaultMaxTCPConnections );
2938+
WebServerPoll->setLimiter( net::Defaults.maxTCPConnections );
29332939

29342940
#if !MOBILEAPP
29352941
net::AsyncDNS::startAsyncDNS();

wsd/DocumentBroker.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ class DocumentBroker::DocumentBrokerPoll final : public TerminatingPoll
139139
TerminatingPoll(threadName),
140140
_docBroker(docBroker)
141141
{
142-
setLimiter( SocketPoll::DefaultMaxTCPConnections );
142+
setLimiter( net::Defaults.maxTCPConnections );
143143
}
144144

145145
void pollingThread() override

0 commit comments

Comments
 (0)