Maintain publish order even when throttling.

Summary: When broker sets receive maximum, and multiple messages with QoS 0 and QoS > 0 are published at the same time, we should maintain order in which async_publish calls were made. Before, QoS > 0 publishes would always be put at the end of the buffer.

Reviewers: ivica

Reviewed By: ivica

Subscribers: korina

Differential Revision: https://repo.mireo.local/D28456
This commit is contained in:
Bruno Iljazovic
2024-03-22 10:38:39 +01:00
parent aea5175e8a
commit 174b0c312f
2 changed files with 161 additions and 19 deletions

View File

@@ -40,7 +40,7 @@ public:
}
asio::const_buffer buffer() const {
return _buffer;
return _buffer;
}
void complete(error_code ec) {
@@ -54,6 +54,10 @@ public:
);
}
bool empty() const {
return !_handler;
}
auto get_executor() {
return asio::get_associated_executor(_handler);
}
@@ -235,29 +239,24 @@ private:
write_queue = std::move(_write_queue);
}
else {
auto throttled_ptr = std::stable_partition(
_write_queue.begin(), _write_queue.end(),
[](const auto& op) { return !op.throttled(); }
);
uint16_t dist = static_cast<uint16_t>(
std::distance(throttled_ptr, _write_queue.end())
);
uint16_t throttled_num = std::min(dist, _quota);
_quota -= throttled_num;
throttled_ptr += throttled_num;
for (write_req& req : _write_queue)
if (!req.throttled())
write_queue.push_back(std::move(req));
else if (_quota > 0) {
--_quota;
write_queue.push_back(std::move(req));
}
if (throttled_ptr == _write_queue.begin()) {
if (write_queue.empty()) {
_write_in_progress = false;
return;
}
write_queue.insert(
write_queue.end(),
std::make_move_iterator(_write_queue.begin()),
std::make_move_iterator(throttled_ptr)
auto it = std::remove_if(
_write_queue.begin(), _write_queue.end(),
[](const write_req& req) { return req.empty(); }
);
_write_queue.erase(_write_queue.begin(), throttled_ptr);
_write_queue.erase(it, _write_queue.end());
}
std::vector<asio::const_buffer> buffers;