mirror of
https://github.com/typesense/typesense.git
synced 2025-05-17 12:12:35 +08:00
More careful handling of custom request data destruction.
This commit is contained in:
parent
ea835bf17f
commit
c5b55a4ca3
@ -3,21 +3,22 @@
|
||||
#include <cstdlib>
|
||||
#include <vector>
|
||||
#include "collection.h"
|
||||
#include "http_data.h"
|
||||
|
||||
struct deletion_state_t {
|
||||
struct deletion_state_t: public req_state_t {
|
||||
Collection* collection;
|
||||
std::vector<std::pair<size_t, uint32_t*>> index_ids; // ids_len -> ids
|
||||
std::vector<size_t> offsets;
|
||||
size_t num_removed;
|
||||
|
||||
~deletion_state_t() {
|
||||
~deletion_state_t() override {
|
||||
for(auto& kv: index_ids) {
|
||||
delete [] kv.second;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct export_state_t {
|
||||
struct export_state_t: public req_state_t {
|
||||
Collection* collection;
|
||||
std::vector<std::pair<size_t, uint32_t*>> index_ids;
|
||||
std::vector<size_t> offsets;
|
||||
@ -29,7 +30,7 @@ struct export_state_t {
|
||||
|
||||
rocksdb::Iterator* it = nullptr;
|
||||
|
||||
~export_state_t() {
|
||||
~export_state_t() override {
|
||||
for(auto& kv: index_ids) {
|
||||
delete [] kv.second;
|
||||
}
|
||||
|
@ -200,6 +200,11 @@ struct ip_addr_str_t {
|
||||
char ip[IP_MAX_LEN];
|
||||
};
|
||||
|
||||
struct req_state_t {
|
||||
public:
|
||||
virtual ~req_state_t() = default;
|
||||
};
|
||||
|
||||
struct http_req {
|
||||
static constexpr const char* AUTH_HEADER = "x-typesense-api-key";
|
||||
static constexpr const char* AGENT_HEADER = "user-agent";
|
||||
@ -220,7 +225,7 @@ struct http_req {
|
||||
size_t body_index;
|
||||
std::string metadata;
|
||||
|
||||
void* data;
|
||||
req_state_t* data;
|
||||
|
||||
// for deffered processing of async handlers
|
||||
h2o_custom_timer_t defer_timer;
|
||||
@ -291,6 +296,9 @@ struct http_req {
|
||||
<< client_ip << " " << full_url_path;
|
||||
}
|
||||
}
|
||||
|
||||
delete data;
|
||||
data = nullptr;
|
||||
}
|
||||
|
||||
void wait() {
|
||||
|
@ -592,6 +592,9 @@ bool get_export_documents(const std::shared_ptr<http_req>& req, const std::share
|
||||
if(req->data == nullptr) {
|
||||
export_state = new export_state_t();
|
||||
|
||||
// destruction of data is managed by req destructor
|
||||
req->data = export_state;
|
||||
|
||||
std::string simple_filter_query;
|
||||
|
||||
if(req->params.count(FILTER_BY) != 0) {
|
||||
@ -620,7 +623,6 @@ bool get_export_documents(const std::shared_ptr<http_req>& req, const std::share
|
||||
req->last_chunk_aggregate = true;
|
||||
res->final = true;
|
||||
stream_response(req, res);
|
||||
delete export_state;
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -631,11 +633,9 @@ bool get_export_documents(const std::shared_ptr<http_req>& req, const std::share
|
||||
export_state->collection = collection.get();
|
||||
}
|
||||
} else {
|
||||
export_state = static_cast<export_state_t*>(req->data);
|
||||
export_state = dynamic_cast<export_state_t*>(req->data);
|
||||
}
|
||||
|
||||
req->data = export_state;
|
||||
|
||||
if(export_state->it != nullptr) {
|
||||
rocksdb::Iterator* it = export_state->it;
|
||||
|
||||
@ -670,8 +670,6 @@ bool get_export_documents(const std::shared_ptr<http_req>& req, const std::share
|
||||
} else {
|
||||
req->last_chunk_aggregate = true;
|
||||
res->final = true;
|
||||
delete export_state;
|
||||
req->data = nullptr;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -684,8 +682,6 @@ bool get_export_documents(const std::shared_ptr<http_req>& req, const std::share
|
||||
} else {
|
||||
req->last_chunk_aggregate = true;
|
||||
res->final = true;
|
||||
delete export_state;
|
||||
req->data = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1038,6 +1034,9 @@ bool del_remove_documents(const std::shared_ptr<http_req>& req, const std::share
|
||||
|
||||
if(req->data == nullptr) {
|
||||
deletion_state = new deletion_state_t{};
|
||||
// destruction of data is managed by req destructor
|
||||
req->data = deletion_state;
|
||||
|
||||
auto filter_ids_op = collection->get_filter_ids(simple_filter_query, deletion_state->index_ids);
|
||||
|
||||
if(!filter_ids_op.ok()) {
|
||||
@ -1045,7 +1044,6 @@ bool del_remove_documents(const std::shared_ptr<http_req>& req, const std::share
|
||||
req->last_chunk_aggregate = true;
|
||||
res->final = true;
|
||||
stream_response(req, res);
|
||||
delete deletion_state;
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1054,9 +1052,8 @@ bool del_remove_documents(const std::shared_ptr<http_req>& req, const std::share
|
||||
}
|
||||
deletion_state->collection = collection.get();
|
||||
deletion_state->num_removed = 0;
|
||||
req->data = deletion_state;
|
||||
} else {
|
||||
deletion_state = static_cast<deletion_state_t*>(req->data);
|
||||
deletion_state = dynamic_cast<deletion_state_t*>(req->data);
|
||||
}
|
||||
|
||||
bool done = true;
|
||||
@ -1077,10 +1074,8 @@ bool del_remove_documents(const std::shared_ptr<http_req>& req, const std::share
|
||||
response["num_deleted"] = deletion_state->num_removed;
|
||||
|
||||
req->last_chunk_aggregate = true;
|
||||
req->data = nullptr;
|
||||
res->body = response.dump();
|
||||
res->final = true;
|
||||
delete deletion_state;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,14 @@
|
||||
std::string HttpClient::api_key = "";
|
||||
std::string HttpClient::ca_cert_path = "";
|
||||
|
||||
struct client_state_t: public req_state_t {
|
||||
CURL* curl;
|
||||
|
||||
client_state_t(CURL* curl): curl(curl) {
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
long HttpClient::post_response(const std::string &url, const std::string &body, std::string &response,
|
||||
std::map<std::string, std::string>& res_headers, long timeout_ms) {
|
||||
CURL *curl = init_curl(url, response);
|
||||
@ -204,7 +212,8 @@ size_t HttpClient::curl_write_async(char *buffer, size_t size, size_t nmemb, voi
|
||||
|
||||
// set headers if not already set
|
||||
if(req_res->res->status_code == 0) {
|
||||
CURL* curl = req_res->req->data;
|
||||
client_state_t* client_state = dynamic_cast<client_state_t*>(req_res->req->data);
|
||||
CURL* curl = client_state->curl;
|
||||
long http_code = 500;
|
||||
CURLcode res = curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, &http_code);
|
||||
if(res == CURLE_OK) {
|
||||
@ -267,7 +276,7 @@ CURL *HttpClient::init_curl_async(const std::string& url, deferred_req_res_t* re
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
req_res->req->data = curl;
|
||||
req_res->req->data = new client_state_t(curl); // destruction of data is managed by req destructor
|
||||
|
||||
std::string api_key_header = std::string("x-typesense-api-key: ") + HttpClient::api_key;
|
||||
chunk = curl_slist_append(chunk, api_key_header.c_str());
|
||||
|
Loading…
x
Reference in New Issue
Block a user