2#ifndef _KURLYK_HTTP_REQUEST_MANAGER_HPP_INCLUDED
3#define _KURLYK_HTTP_REQUEST_MANAGER_HPP_INCLUDED
33 std::unique_ptr<HttpRequest> request_ptr,
36 std::lock_guard<std::mutex> lock(
m_mutex);
37# if __cplusplus >= 201402L
38 m_pending_requests.push_back(std::make_unique<HttpRequestContext>(std::move(request_ptr), std::move(callback)));
51 return m_rate_limiter.create_limit(requests_per_period, period_ms);
72 if (callback) callback();
75 std::lock_guard<std::mutex> lock(
m_mutex);
101 std::lock_guard<std::mutex> lock(
m_mutex);
122 std::unique_lock<std::mutex> lock(
m_mutex);
125 std::vector<std::unique_ptr<HttpRequestContext>> pending_request;
126 std::vector<std::unique_ptr<HttpRequestContext>> failed_requests;
131 auto& request = context->request;
134 failed_requests.push_back(std::move(context));
141 request->general_rate_limit_id,
142 request->specific_rate_limit_id);
147 pending_request.push_back(std::move(context));
153 if (!failed_requests.empty()) {
154 for (
const auto &context : failed_requests) {
155# if __cplusplus >= 201402L
156 auto response = std::make_unique<HttpResponse>();
158 auto response = std::unique_ptr<HttpResponse>(
new HttpResponse());
160 const long BAD_REQUEST = 400;
162 response->status_code = BAD_REQUEST;
163 response->ready =
true;
164 context->callback(std::move(response));
166 failed_requests.clear();
170 if (pending_request.empty())
return;
171# if __cplusplus >= 201402L
183 if (!request->process()) {
187 auto failed_requests = request->extract_failed_requests();
189 for (
auto& request : failed_requests) {
199 auto& request_context = *it;
200 if (!request_context || !request_context->request) {
205 const auto now = std::chrono::steady_clock::now();
206 const auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(now - request_context->start_time);
207 const auto& retry_delay_ms = request_context->request->retry_delay_ms;
208 if (duration.count() >= retry_delay_ms) {
209 std::unique_lock<std::mutex> lock(
m_mutex);
221 std::unique_lock<std::mutex> lock(
m_mutex);
229 if (!requests_to_cancel.count(request_context->request->request_id))
continue;
230# if __cplusplus >= 201402L
231 auto response = std::make_unique<HttpResponse>();
233 auto response = std::unique_ptr<HttpResponse>(
new HttpResponse());
235 const long CANCELED_REQUEST_CODE = 499;
237 response->status_code = CANCELED_REQUEST_CODE;
238 response->ready =
true;
239 request_context->callback(std::move(response));
242 m_failed_requests.remove_if([&](
const std::unique_ptr<HttpRequestContext>& ctx) {
243 return ctx && ctx->request && requests_to_cancel.count(ctx->request->request_id) > 0;
248 handler->cancel_request_by_id(requests_to_cancel);
251 for (
const auto &request : requests_to_cancel) {
252 for (
const auto &callback : request.second) {
253 if (callback) callback();
260 std::unique_lock<std::mutex> lock(
m_mutex);
265 for (
const auto &request_context : pending_requests) {
266# if __cplusplus >= 201402L
267 auto response = std::make_unique<HttpResponse>();
269 auto response = std::unique_ptr<HttpResponse>(
new HttpResponse());
271 const long CANCELED_REQUEST_CODE = 499;
273 response->status_code = CANCELED_REQUEST_CODE;
274 response->ready =
true;
275 request_context->callback(std::move(response));
278# if __cplusplus >= 201402L
279 auto response = std::make_unique<HttpResponse>();
281 auto response = std::unique_ptr<HttpResponse>(
new HttpResponse());
283 const long CANCELED_REQUEST_CODE = 499;
285 response->status_code = CANCELED_REQUEST_CODE;
286 response->ready =
true;
287 request_context->callback(std::move(response));
293 curl_global_init(CURL_GLOBAL_ALL);
298 curl_global_cleanup();
Manages multiple asynchronous HTTP requests using libcurl's multi interface.
Defines the HttpRateLimiter class for managing rate limits on HTTP requests.
Defines the HttpRequestContext class for managing HTTP request context, including retries and timing.
Handles multiple asynchronous HTTP requests using libcurl's multi interface.
Manages rate limits for HTTP requests, ensuring compliance with set limits.
Represents the context of an HTTP request, including the request object, callback function,...
HttpRequestManager(const HttpRequestManager &)=delete
Deleted copy constructor to enforce the singleton pattern.
std::atomic< bool > m_shutdown
Flag indicating if shutdown has been requested.
const bool add_request(std::unique_ptr< HttpRequest > request_ptr, HttpResponseCallback callback)
Adds a new HTTP request to the manager.
std::unordered_map< uint64_t, callback_list_t > m_requests_to_cancel
Map of request IDs to their associated cancellation callbacks.
const long create_rate_limit(long requests_per_period, long period_ms)
Creates a rate limit with specified parameters.
std::list< std::unique_ptr< HttpRequestContext > > m_failed_requests
List of failed HTTP requests for retrying.
void process_active_requests()
Processes active requests, moving failed ones to the failed requests list for retrying.
void cancel_request_by_id(uint64_t request_id, std::function< void()> callback)
Cancels a request by its unique identifier.
static HttpRequestManager & get_instance()
Get the singleton instance of HttpRequestManager.
std::list< std::unique_ptr< HttpBatchRequestHandler > > m_active_request_batches
List of currently active HTTP request batches.
std::atomic< uint64_t > m_request_id_counter
Atomic counter for unique request IDs.
void process_retry_failed_requests()
Attempts to retry failed requests if their retry delay has passed.
virtual ~HttpRequestManager()
Private destructor to clean up global resources.
HttpRateLimiter m_rate_limiter
Rate limiter for controlling request frequency.
std::list< std::function< void()> > callback_list_t
const bool is_loaded() const override
Checks if there are active, pending, or failed requests.
std::mutex m_mutex
Mutex to protect access to the pending requests list and requests-to-cancel map.
void process_cancel_requests()
Processes and cancels HTTP requests based on their IDs.
bool remove_limit(long limit_id)
Removes an existing rate limit with the specified identifier.
uint64_t generate_request_id()
Generates a new unique request ID.
void shutdown() override
Shuts down the request manager, clearing all active and pending requests.
HttpRequestManager & operator=(const HttpRequestManager &)=delete
Deleted copy assignment operator to enforce the singleton pattern.
HttpRequestManager()
Private constructor to initialize global resources (e.g., cURL).
void cleanup_pending_requests()
Cleans up pending requests, marking each as failed and invoking its callback.
void process() override
Processes all requests in the manager.
void process_pending_requests()
Processes all pending requests, moving valid requests to active batches or marking them as failed.
std::list< std::unique_ptr< HttpRequestContext > > m_pending_requests
List of pending HTTP requests awaiting processing.
Represents the response received from an HTTP request, including headers, content,...
Interface for modules managed by NetworkWorker (e.g., HTTP, WebSocket).
std::error_code make_error_code(ClientError e)
Creates a std::error_code from a ClientError value.
Primary namespace for the Kurlyk library, encompassing initialization, request management,...
std::function< void(HttpResponsePtr response)> HttpResponseCallback
Type definition for the callback function used to handle HTTP responses.