Maintain outgoing bytes queued count

This commit is contained in:
2025-08-24 11:04:26 -04:00
parent c0242317ed
commit e56cf41a01
2 changed files with 18 additions and 6 deletions

View File

@@ -43,6 +43,7 @@ void Connection::appendMessage(std::string_view s, bool copy_to_arena) {
} else { } else {
messages_.push_back(s); messages_.push_back(s);
} }
outgoing_bytes_queued_ += s.size();
} }
int Connection::readBytes(char *buf, size_t buffer_size) { int Connection::readBytes(char *buf, size_t buffer_size) {
@@ -104,6 +105,7 @@ bool Connection::writeBytes() {
// Handle partial writes by updating string_view data/size // Handle partial writes by updating string_view data/size
size_t bytes_written = static_cast<size_t>(w); size_t bytes_written = static_cast<size_t>(w);
outgoing_bytes_queued_ -= bytes_written;
while (bytes_written > 0 && !messages_.empty()) { while (bytes_written > 0 && !messages_.empty()) {
auto &front = messages_.front(); auto &front = messages_.front();

View File

@@ -178,7 +178,7 @@ struct Connection {
/** /**
* @brief Get the number of bytes queued for transmission. * @brief Get the number of bytes queued for transmission.
* *
* Calculates and returns the total number of bytes in all messages currently * Returns the total number of bytes in all messages currently
* queued for transmission to the client. This includes all data added via * queued for transmission to the client. This includes all data added via
* appendMessage() that has not yet been sent over the network. * appendMessage() that has not yet been sent over the network.
* *
@@ -187,8 +187,8 @@ struct Connection {
* @warning Thread Safety: Only call from the thread that currently owns this * @warning Thread Safety: Only call from the thread that currently owns this
* connection. Concurrent access to the message queue is not thread-safe. * connection. Concurrent access to the message queue is not thread-safe.
* *
* @note Performance: This method iterates through all queued messages to * @note Performance: This method uses an O(1) counter for fast retrieval
* calculate the total, so avoid calling it frequently in hot paths. * in release builds. In debug builds, validates counter accuracy.
* *
* @note The count decreases as the server sends data via writeBytes() and * @note The count decreases as the server sends data via writeBytes() and
* removes completed messages from the queue. * removes completed messages from the queue.
@@ -210,11 +210,17 @@ struct Connection {
* ``` * ```
*/ */
int64_t outgoingBytesQueued() const { int64_t outgoingBytesQueued() const {
int64_t result = 0; #ifndef NDEBUG
// Debug build: validate counter accuracy
int64_t computed_total = 0;
for (auto s : messages_) { for (auto s : messages_) {
result += s.size(); computed_total += s.size();
} }
return result; assert(
outgoing_bytes_queued_ == computed_total &&
"outgoing_bytes_queued_ counter is out of sync with actual queue size");
#endif
return outgoing_bytes_queued_;
} }
/** /**
@@ -282,6 +288,7 @@ struct Connection {
*/ */
void reset() { void reset() {
assert(messages_.empty()); assert(messages_.empty());
outgoing_bytes_queued_ = 0;
arena_.reset(); arena_.reset();
messages_ = messages_ =
std::deque<std::string_view, ArenaStlAllocator<std::string_view>>{ std::deque<std::string_view, ArenaStlAllocator<std::string_view>>{
@@ -345,6 +352,9 @@ private:
std::deque<std::string_view, ArenaStlAllocator<std::string_view>> messages_{ std::deque<std::string_view, ArenaStlAllocator<std::string_view>> messages_{
ArenaStlAllocator<std::string_view>{&arena_}}; ArenaStlAllocator<std::string_view>{&arena_}};
// Counter tracking total bytes queued for transmission
int64_t outgoing_bytes_queued_{0};
// Whether or not to close the connection after completing writing the // Whether or not to close the connection after completing writing the
// response // response
bool closeConnection_{false}; bool closeConnection_{false};