-
Notifications
You must be signed in to change notification settings - Fork 692
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Handle limited open Connections due to keepalive connections #9916
base: master
Are you sure you want to change the base?
Conversation
a2c3068
to
3ef99c5
Compare
This change set created a linkage error (android), the 'usual' type_info, vtable thing. |
net/Socket.cpp
Outdated
@@ -1298,6 +1385,52 @@ LocalServerSocket::~LocalServerSocket() | |||
# define LOG_CHUNK(X) | |||
#endif | |||
|
|||
bool StreamSocket::checkForcedRemoval(std::chrono::steady_clock::time_point now) noexcept |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
might need to move this impl to after
"#endif // !MOBILEAPP" (if mobile needs it) and/or put ifdef MOBILEAPP around it in the header if it doesn't or a !MOBILE stub, something like that anyway
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah. Great eyes. Thx!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, @sgothel. There are some really good stuff here!
I understand this is a draft, but it reads like a mix of random fixes and improvements (some of it is good and useful, like adding const
and = default
, make_shared
, etc.), re-inventing methods for doing things already supported, and debugging/tracing support for your understanding (to be removed).
It's very hard to read, as there is no clear theme or purpose.
I left various comments, but I didn't dive too deep in a number of areas because it was unclear why we are either replacing an existing approach, or inventing a new one when we can improve on the existing one (where there are shortcomings).
At a minimum, I'd separate the backtrace improvements from the socket improvements, and likely the misc. improvements from new code/features/tests.
Finally, I'm troubled by vformatString
and the re-working a lot of the socket states and internals with a huge set of new members that change the existing semantics with unclear benefits.
Perhaps there is some context I'm missing. Perhaps this was agreed on and I'm unaware.
Thank you @Ashod for the review.
The draft status was motivated by my intention to discuss the actual semantics and goals, Which brings us to the next point I guess.
When reading commit by commit, I believe everything is well split apart semantically. Indeed, I added a few unrelated single commits into this review. Understanding that we allow
I am not aware of really replacing anything. I merely moved and added functionality.
As described above, a zero side-effect change in its own commit. The Backtrace object in particular is useful for all, as we can produce an instance
I just like printf formatting as it is more performant and flexible (at least to me).
Allow me to continue answering your other remarks below. |
2d51475
to
508ccb0
Compare
I think it'll be easier to manage this if its split up so that the mostly uncontroversial misc cleanups of existing stuff where no change in logic is intended, the make_unique, make_shared, privator ctor -> = delete, constifying, expansion of auto& to real type, emplace_back, etc goes into a separate pr. The backtrace debugging aid looks probably useful to have to me, but can also be its own pr I think (and probably not worth fighting the "CodeQL scanning - action / Analyze" step which apparently can't handle the constexpr use which is blocking ci from passing this pr). And generally trim this pr down to the core change to make it easier to think about it |
Thanks for the responses, @sgothel! We've discussed some offline, so didn't reply here (e.g. printf-style formatting being fast--in fact it's very slow compared to only serialization).
In general, agreed. But I'll echo @caolanm's comment here that breaking up into PRs, that can be decided to merge independent of other parts, is always helpful. I should also point out that this PR is well above a 1000 lines. This is a rare size. Considering that some parts change the interface of a large hierarchy (the sockets), which is a fundamental core part of the whole project and very delicate (can easily break things catastrophically), it requires reading and studying far more code (i.e. the context and consequences) to review properly. An isolated and low-risk change of a few 100 lines is fine. A complex few 100 line change (such as in the sockets) is challenging and time consuming. Sometimes we have no choice because we can't break it up. But a 1000 lines that can be easily broken up is hardly necessary. Finally, even though we can review individual commits, it's preferable to have a single theme to a PR. Helps the reviewer. In some cases a few misc. changes can go together (comment fixes, cosmetics, formatting, logging, etc.). But mixing functional changes with non-functional changes dilutes the process and can reduce the quality of the review. More so with high-risk changes (i.e. socket code) mixed with debugging code (i.e. backtracing). Regardless, you have a lot of great improvements here, and I don't want to undermine the importance of your contribution! |
508ccb0
to
cb801db
Compare
Thank you both for your review and kind words. I have split up single commits into 4 branches, i.e. this pull-request branch and
For this feature work, I need to complete the unit test incl. the timeout configuration. |
cb801db
to
6fc374e
Compare
6fc374e
to
31c1b94
Compare
@sgothel, there were multiple suggestions to split this large PR up to reduce its size. That was when it had 18 commits and was "only" a 1000 lines. Now it's past 1500 lines and is 1 commit! I'm sensing this isn't going in the direction of the feedback. What's the plan, please? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As said needs to be split up; lets try to get the less controversial pieces in and merged as separate pull requests - to slim this down =) Can you work on that Sven ?
will do the split later then (tomorrow) + finishing the tests |
As I wrote, I will split out the config and TimeAverage (~400 lines or so) and put the remainder at the bottom -> 3 commits within this pull request. Perhaps more, w/ a fresh look. But splitting this up in multiple pull request (PR) makes would probably makes no sense, as these pieces are required and each PR must be tested. IMHO. |
Added minor changes addressing @Ashod earlier notes. |
Note: Unit tests: +7 files, 879 insertions(+), remaining changed lines +800, -222 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok - this is great; thanks Sven & Caolan - much easier to review, can go in at the beginning of the next Red merge window; ignore my comments about unit tests - I see them at the end; other minor cleanups can come later / get tacked on.
Nice work - thanks ! =)
Actually - I lie the c1,2,3,4 thing really needs fixing or explaining; its not clear to me that it will work =) |
fe29153
to
62a5cc2
Compare
I apologize: Should have pushed with a rebase to master 1st, then another push with the changes. |
Preparation for cool#9833. Socket Restructuring: - Hoist open/close state from StreamSocket to Socket Signed-off-by: Sven Göthel <[email protected]> Change-Id: I7e1a9329e0848c40a210f6250e29e26950da6fbc
…own. SocketPoll::poll robustness Preparation for cool#9833. Socket Restructuring: - Unify closing SocketPoll::poll robustness - Ensure erasing Socket if !isOpen() Signed-off-by: Sven Göthel <[email protected]> Change-Id: I7e1a9329e0848c40a210f6250e29e26950da6fbc
…hutdown* Preparation for cool#9833. WebSocketHandler::shutdown* - Add shutdownSilent(), preparation to force shutdown on timeout w/o closing frame. Signed-off-by: Caolán McNamara <[email protected]> Signed-off-by: Sven Göthel <[email protected]> Change-Id: I68d1d18311a059f94b84ef1867f8343ef7a09c1d
Signed-off-by: Caolán McNamara <[email protected]> Signed-off-by: Sven Göthel <[email protected]> Change-Id: Ia79f8027eb5cc8911d5cdf71ba1a73fdd1b0dde3
Signed-off-by: Caolán McNamara <[email protected]> Signed-off-by: Sven Göthel <[email protected]> Change-Id: I9c34d3d9b2caf4aa0e9ba09782bf4a51c5e9a239
Signed-off-by: Caolán McNamara <[email protected]> Signed-off-by: Sven Göthel <[email protected]> Change-Id: I9c5302b292c406bdf05eb031615a93d8939b0a88
Signed-off-by: Caolán McNamara <[email protected]> Signed-off-by: Sven Göthel <[email protected]> Change-Id: Ifaa7ea79d05d0f1580a6f8ffcc6db66814005199
Signed-off-by: Caolán McNamara <[email protected]> Signed-off-by: Sven Göthel <[email protected]> Change-Id: If736c3e1b00fbadd15504e97970a6d4d8f5873d7
- DelaySocket::State - ServerSocket::Type - ::SharedFDType, - StreamSocket::ReadType - StreamSocket::WSState Signed-off-by: Caolán McNamara <[email protected]> Signed-off-by: Sven Göthel <[email protected]> Change-Id: I33c1a233632b25d0632a9130a03aee2991a6e3e7
Preparation for cool#9833, to be used to provide a time-based ping response time average. TimeAverage allows us to calculate the time based average of a value while adding new time-point/value tuples at arbitrary time-points. The result is stable against small fluctuations and shall provide a reasonable actionable criteria. Signed-off-by: Sven Göthel <[email protected]> Change-Id: I7e1a9329e0848c40a210f6250e29e26950da6fbc
…imeout) Preparation for cool#9833. Using runtime mutable defaults for network properties allows us to test the socket limitation code as well as to fine-tune certain properties for clients. Costs are removal of constexpr properties, using a static local (singleton) instance, cached where used - hence rendering the code less optimized and more pessimistic. However, the singleton instance is fetched at object creation w/o cache hit using a static-local, networking timing outweights memory reads and no hot-spot performance heavy loop is affected. Hence rendering the feature testable at runtime shall outweight the lesser costs. - All network limits and timeouts are configurable within our unit tests only - see net::Defaults in NetUtil.hpp Signed-off-by: Sven Göthel <[email protected]> Signed-off-by: Caolán McNamara <[email protected]> Change-Id: I7e1a9329e0848c40a210f6250e29e26950da6fbc
…as creationTime to ctor This could reduce costs involved via std::chrono::steady_clock::now(), but also allows socket creation using a dedicated time-point. Signed-off-by: Caolán McNamara <[email protected]> Signed-off-by: Sven Göthel <[email protected]> Change-Id: I7e1a9329e0848c40a210f6250e29e26950da6fbc
…incl. creation- and lastSeenTime Socket Restructuring: - Unify stats(bytes + throughput) - Persistent creationTime (immutable) and lastSeenTime (mutable) Signed-off-by: Caolán McNamara <[email protected]> Signed-off-by: Sven Göthel <[email protected]> Change-Id: If9e3b28cfd4c6fdb73b978b80ef2063c63def6d1
moved `StreamSocket::_lastSeenHTTPHeader` to `std::chrono::steady_clock::time_point &lastHTTPHeader` where it is being required - reduces general footprint. Signed-off-by: Sven Göthel <[email protected]> Signed-off-by: Caolán McNamara <[email protected]> Change-Id: I5148fa7ee2aa5ce88ef8bf31c2e036921d01277c
- ProtocolHandlerInterface::checkTimeout(..) is now called via StreamSocket::checkRemoval() to ensure tests even w/o input data (was: handlePoll()) - ProtocolHandlerInterface::checkTimeout(..) - Add bool return value: true -> shutdown connection, caller shall stop processing - Implemented for http::Session - Timeout (30s) net::Defaults::HTTPTimeout with missing response - Implemented for WebSocketHandler - Timeout (2s = net::Defaults::WSPingTimeout) after missing WS native frame ping/pong (server only) - StreamSocket::checkRemoval(..) - called directly from SocketPoll::poll() - only for IPv4/v6 network connections - similar to ProtocolHandlerInterface::checkTimeout(..) - calls ProtocolHandlerInterface::checkTimeout(..) - added further criteria (throughput, ..) - Timeout (64s = net::Defaults::SocketPollTimeout) if (now - lastSeen) > timeout - Timeout (net::Defaults::MinBytesPerSec) if Throughput < MinBytesPerSec (disabled by default) - TODO: Add maximal IPv4/IPv6 socket-count criteria, drop oldest. - age via Socket::creationTime is currently not used as requested - SocketPoll::poll() - Additionally erases if !socket->isOpen() || socket->checkRemoval() Signed-off-by: Sven Göthel <[email protected]> Signed-off-by: Caolán McNamara <[email protected]> Change-Id: I7e1a9329e0848c40a210f6250e29e26950da6fbc
Adding connection limit where registered via SocketPoll::setLimiter(), i.e. DocumentBrokerPoll and WebServerPoll only. SocketPoll::poll() will drop _new_ overhead connections exceeding MaxConnections. This has been discussed, in favor of dropping the oldest connections. Aligned net::Defaults::MaxConnections w/ pre-existing MAX_CONNECTIONS. SocketPoll::setLimiter(): - Increments given non-zero connectionLimit by one for WS upgrade socket. Signed-off-by: Sven Göthel <[email protected]> Change-Id: I7e1a9329e0848c40a210f6250e29e26950da6fbc
test/UnitTimeoutBase.hpp - Base for UnitTimeout* tests test/UnitTimeoutNone.cpp - Test without limitation, no disconnection test/UnitTimeoutConnections.cpp - Test disconnection with limited max-connections (5) via net::Defaults test/UnitTimeoutWSPing.cpp - Test disconnection with limited WSPingTimout (20us) using WSPingPeriod (10ms) via net::Defaults test/UnitTimeoutSocket.cpp - Test disconnection with limited MinBytesPerSec (100kBps) via net::Defaults test/WebSocketSession's WebSocketSession::poll() added a isConnected() check allowing to abort. Signed-off-by: Sven Göthel <[email protected]> Change-Id: I7e1a9329e0848c40a210f6250e29e26950da6fbc
Signed-off-by: Sven Göthel <[email protected]> Signed-off-by: Caolán McNamara <[email protected]> Change-Id: I9f7a6fbbf93381de72471ea878582f8e5db88962
62a5cc2
to
acc1d92
Compare
resolved merge conflict due to changed net/Socket.* |
Summary
ProtocolHandlerInterface::checkTimeout(..)
is now called via StreamSocket::checkRemoval()
to ensure tests even w/o input data (was: handlePoll())
ProtocolHandlerInterface::checkTimeout(..)
after missing WS native frame ping/pong (server only)
StreamSocket -> Socket (properties moved)
Socket (added properties)
if (now - lastSeen) > timeout
if Throughput < MinBytesPerSec (disabled by default)
SocketPoll::poll()
Changes to original PR
Further:
and before moved _lastSeenHTTPHeader
git rebase -i --exec "make -j 20"
for all commitsUnit tests: +7 files, 879 insertions(+), remaining changed lines +800, -222
Checklist
make prettier-write
and formatted the code.make check
make run
and manually verified that everything looks okay