Kurlyk
Loading...
Searching...
No Matches
HttpBatchRequestHandler.hpp
Go to the documentation of this file.
1#pragma once
2#ifndef _KURLYK_HTTP_MULTI_REQUEST_HANDLER_HPP_INCLUDED
3#define _KURLYK_HTTP_MULTI_REQUEST_HANDLER_HPP_INCLUDED
4
7
8namespace kurlyk {
9
13 public:
14
17 explicit HttpBatchRequestHandler(std::vector<std::unique_ptr<HttpRequestContext>>& context_list)
18 : m_multi_handle(curl_multi_init()) {
19 for (auto& context : context_list) {
20# if __cplusplus >= 201402L
21 auto handler = std::make_unique<HttpRequestHandler>(std::move(context));
22# else
23 auto handler = std::unique_ptr<HttpRequestHandler>(new HttpRequestHandler(std::move(context)));
24# endif
25 CURL* curl = handler->get_curl();
26 if (!curl) continue;
27
28 curl_multi_add_handle(m_multi_handle, curl);
29 m_handlers.push_back(std::move(handler));
30 }
31 }
32
35 for (auto& handler : m_handlers) {
36 CURL* curl = handler->get_curl();
37 if (!curl) continue;
38 curl_multi_remove_handle(m_multi_handle, curl);
39 }
40 curl_multi_cleanup(m_multi_handle);
41 }
42
45 bool process() {
46 int still_running = 0;
47 CURLMcode res = curl_multi_perform(m_multi_handle, &still_running);
48 if (res != CURLM_OK) return false;
49
50 int pending_messages;
51 while (CURLMsg* message = curl_multi_info_read(m_multi_handle, &pending_messages)) {
52 if (message->msg != CURLMSG_DONE) continue;
54 }
55 if (still_running == 0) {
56 m_handlers.clear();
57 return true;
58 }
59 return false;
60 }
61
64 std::list<std::unique_ptr<HttpRequestContext>> extract_failed_requests() {
65 return std::move(m_failed_requests);
66 }
67
70 void cancel_request_by_id(const std::unordered_map<uint64_t, std::list<std::function<void()>>>& to_cancel) {
71 auto it = m_handlers.begin();
72 while (it != m_handlers.end()) {
73 uint64_t id = (*it)->get_request_id();
74 if (!to_cancel.count(id)) {
75 ++it;
76 continue;
77 }
78 curl_multi_remove_handle(m_multi_handle, (*it)->get_curl());
79 (*it)->cancel(); // Cancel the request.
80 it = m_handlers.erase(it);
81 }
82 }
83
84 private:
85 CURLM* m_multi_handle = nullptr;
86 std::vector<std::unique_ptr<HttpRequestHandler>> m_handlers;
87 std::list<std::unique_ptr<HttpRequestContext>> m_failed_requests;
88
91 void handle_completed_request(CURLMsg* message) {
92 CURL* curl = message->easy_handle;
93
94 void* ptr = nullptr;
95 curl_easy_getinfo(curl, CURLINFO_PRIVATE, &ptr);
96 auto* handler = static_cast<HttpRequestHandler*>(ptr);
97 if (!handler) return;
98
99 if (!handler->handle_curl_message(message)) {
100 m_failed_requests.push_back(handler->get_request_context());
101 }
102 curl_multi_remove_handle(m_multi_handle, curl);
103 }
104
105 }; // HttpBatchRequestHandler
106
107} // namespace kurlyk
108
109#endif // _KURLYK_HTTP_MULTI_REQUEST_HANDLER_HPP_INCLUDED
void cancel_request_by_id(const std::unordered_map< uint64_t, std::list< std::function< void()> > > &to_cancel)
Cancels HTTP requests based on their unique IDs.
std::list< std::unique_ptr< HttpRequestContext > > m_failed_requests
List of failed request contexts.
void handle_completed_request(CURLMsg *message)
Handles the completion of a single request.
bool process()
Processes the requests within the handler.
std::list< std::unique_ptr< HttpRequestContext > > extract_failed_requests()
Extracts the list of failed requests.
std::vector< std::unique_ptr< HttpRequestHandler > > m_handlers
Collection of active request handlers.
HttpBatchRequestHandler(std::vector< std::unique_ptr< HttpRequestContext > > &context_list)
Constructs a handler for managing multiple HTTP requests asynchronously.
~HttpBatchRequestHandler()
Cleans up the multi handle and removes all request handles.
CURLM * m_multi_handle
libcurl multi handle.
Manages asynchronous HTTP requests, including handling responses, retries, and error processing.
Primary namespace for the Kurlyk library, encompassing initialization, request management,...