Skip to content

Commit

Permalink
fix: https request queues still need a removals queue, it can be simp…
Browse files Browse the repository at this point in the history
…lified but needs to still exist, there is a chicken-and-egg situation with the pointer for the request
  • Loading branch information
braindigitalis committed Dec 4, 2024
1 parent 6a76049 commit 0d5e932
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 18 deletions.
10 changes: 10 additions & 0 deletions include/dpp/queues.h
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,11 @@ class DPP_EXPORT http_request {

/** @brief Returns true if the request is complete */
bool is_completed();

/**
* @brief Get the HTTPS client used to perform this request, or nullptr if there is none
*/
https_client* get_client() const;
};

/**
Expand Down Expand Up @@ -470,6 +475,11 @@ class DPP_EXPORT request_concurrency_queue {
*/
std::vector<std::unique_ptr<http_request>> requests_in;

/**
* @brief Requests to remove after a set amount of time has passed
*/
std::vector<std::unique_ptr<http_request>> removals;

/**
* @brief Timer callback
* @param index Index ID for this timer
Expand Down
42 changes: 30 additions & 12 deletions src/dpp/queues.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,11 +107,10 @@ http_request::http_request(const std::string &_url, http_completion_event comple
{
}

http_request::~http_request() = default;
http_request::~http_request() = default;

void http_request::complete(const http_request_completion_t &c) {
/* Call completion handler only if the request has been completed */
if (is_completed() && complete_handler) {
if (complete_handler) {
complete_handler(c);
}
}
Expand Down Expand Up @@ -154,6 +153,11 @@ bool http_request::is_completed()
return completed;
}

https_client* http_request::get_client() const
{
return cli.get();
}

/* Execute a HTTP request */
http_request_completion_t http_request::run(request_concurrency_queue* processor, cluster* owner) {

Expand Down Expand Up @@ -241,7 +245,6 @@ http_request_completion_t http_request::run(request_concurrency_queue* processor
}
populate_result(_url, owner, result, *client);
/* Set completion flag */
completed = true;

bucket_t newbucket;
newbucket.limit = result.ratelimit_limit;
Expand All @@ -257,13 +260,17 @@ http_request_completion_t http_request::run(request_concurrency_queue* processor
processor->buckets[this->endpoint] = newbucket;

/* Transfer it to completed requests */
owner->queue_work(0, [this, result]() {
/* Manually release this unique_ptr now, to keep memory consumption and file descriptor consumption low.
* Note we do this BEFORE we call complete(), becasue if user code throws an exception we need to be sure
* we freed this first to avoid dangling pointer leaks.
*/
this->cli.reset();
complete(result);
owner->queue_work(0, [owner, this, result, hci, _url]() {
try {
complete(result);
}
catch (const std::exception& e) {
owner->log(ll_error, "Uncaught exception thrown in HTTPS callback for " + std::string(request_verb[method]) + " " + hci.hostname + ":" + std::to_string(hci.port) + _url + ": " + std::string(e.what()));
}
catch (...) {
owner->log(ll_error, "Uncaught exception thrown in HTTPS callback for " + std::string(request_verb[method]) + " " + hci.hostname + ":" + std::to_string(hci.port) + _url + ": <non exception value>");
}
completed = true;
});
}
);
Expand Down Expand Up @@ -296,6 +303,17 @@ request_concurrency_queue::request_concurrency_queue(class cluster* owner, class
{
in_timer = creator->start_timer([this](auto timer_handle) {
tick_and_deliver_requests(in_index);
/* Clear pending removals in the removals queue */
if (time(nullptr) % 90 == 0) {
std::scoped_lock lock1{in_mutex};
for (auto it = removals.cbegin(); it != removals.cend();) {
if ((*it)->is_completed()) {
it = removals.erase(it);
} else {
++it;
}
}
}
}, 1);
}

Expand Down Expand Up @@ -385,7 +403,7 @@ void request_concurrency_queue::tick_and_deliver_requests(uint32_t index)
for (auto it = begin; it != end; ++it) {
if (it->get() == request_view) {
/* Grab and remove */
request_view->stash_self(std::move(*it));
removals.emplace_back(std::move(*it));
requests_in.erase(it);
break;
}
Expand Down
16 changes: 10 additions & 6 deletions src/dpp/sslclient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -548,18 +548,22 @@ bool ssl_client::handle_buffer(std::string &buffer)

void ssl_client::close()
{
if (!plaintext && ssl->ssl) {
if (!plaintext) {
std::lock_guard<std::mutex> lock(ssl_mutex);
SSL_free(ssl->ssl);
ssl->ssl = nullptr;
if (ssl != nullptr && ssl->ssl != nullptr) {
SSL_free(ssl->ssl);
ssl->ssl = nullptr;
}
}
connected = tcp_connect_done = false;
client_to_server_length = client_to_server_offset = 0;
last_tick = time(nullptr);
bytes_in = bytes_out = 0;
owner->socketengine->delete_socket(sfd);
close_socket(sfd);
sfd = INVALID_SOCKET;
if (sfd != INVALID_SOCKET) {
owner->socketengine->delete_socket(sfd);
close_socket(sfd);
sfd = INVALID_SOCKET;
}
obuffer.clear();
buffer.clear();
}
Expand Down

0 comments on commit 0d5e932

Please sign in to comment.