Project
Loading...
Searching...
No Matches
CCDBDownloader.h
Go to the documentation of this file.
1// Copyright 2019-2023 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11#ifndef O2_CCDBDOWNLOADER_H_
12#define O2_CCDBDOWNLOADER_H_
13
14#if !defined(__CINT__) && !defined(__MAKECINT__) && !defined(__ROOTCLING__) && !defined(__CLING__)
16#endif
17
18#include <cstdio>
19#include <cstdlib>
20#include <curl/curl.h>
21#include <string>
22#include <vector>
23#include <iostream>
24#include <thread>
25#include <mutex>
26#include <condition_variable>
27#include <unordered_map>
28#include <map>
29#include <functional>
30
31typedef struct uv_loop_s uv_loop_t;
32typedef struct uv_timer_s uv_timer_t;
33typedef struct uv_poll_s uv_poll_t;
34typedef struct uv_signal_s uv_signal_t;
35typedef struct uv_async_s uv_async_t;
36typedef struct uv_handle_s uv_handle_t;
37
38namespace o2::ccdb
39{
40
41#if !defined(__CINT__) && !defined(__MAKECINT__) && !defined(__ROOTCLING__) && !defined(__CLING__)
43 std::multimap<std::string, std::string> header;
44 o2::pmr::vector<char>* object = nullptr;
45 int counter = 0;
46};
47
48typedef struct DownloaderRequestData {
49 std::vector<std::string> hosts;
50 std::vector<std::string> locations;
51 std::string path;
54 std::map<std::string, std::string>* headers;
55 std::string userAgent;
56 // One header list per entry of `hosts`, parallel to it. Per host and not one
57 // shared list because the gate token a broker expects is per endpoint: a
58 // multi-host pool can mix them, and tryNewHost() swapping only the URL left
59 // the second host receiving the first host's token -- answered 401, so the
60 // failover silently retrieved nothing (testCcdbApi multi_host_test).
61 std::vector<curl_slist*> optionsLists;
62
63 std::function<bool(std::string)> localContentCallback;
64} DownloaderRequestData;
65#endif
66
67/*
68 Some functions below aren't member functions of CCDBDownloader because both curl and libuv require callback functions which have to be either static or non-member.
69 Because non-static functions are used in the functions below, they must be non-member.
70*/
71
78void closeHandles(uv_handle_t* handle, void* arg);
79
87curl_socket_t opensocketCallback(void* clientp, curlsocktype purpose, struct curl_sockaddr* address);
88
95
100
109{
110 public:
115 std::unordered_map<curl_socket_t, uv_timer_t*> mSocketTimerMap;
116
121
125 std::unordered_map<uv_handle_t*, bool> mHandleMap;
126
131
136
140 int mRequestTimeoutMS = 300000;
141
146
151
156
157 CCDBDownloader(uv_loop_t* uv_loop = nullptr);
159
165 CURLcode perform(CURL* handle);
166
171 std::vector<CURLcode> batchBlockingPerform(std::vector<CURL*> const& handleVector);
172
179 void asynchSchedule(CURL* handle, size_t* requestCounter);
180
184 void setMaxParallelConnections(int limit);
185
189 void setKeepaliveTimeoutTime(int timeoutMS);
190
194 void setConnectionTimeoutTime(int timeoutMS);
195
199 void setRequestTimeoutTime(int timeoutMS);
200
204 void setHappyEyeballsHeadstartTime(int headstartMS);
205
210
215
221 void runLoop(bool noWait);
222
226 std::string prepareLogMessage(std::string host_url, std::string userAgent, const std::string& path, long ts, const std::map<std::string, std::string>* headers, long httpCode) const;
227
231 std::string trimHostUrl(std::string full_host_url) const;
232
233 private:
237 std::string prepareRedirectedURL(std::string address, std::string potentialHost) const;
238
246 void updateLocations(std::multimap<std::string, std::string>* headerMap, std::vector<std::string>* locations, int* locIndex) const;
247
248 std::string mUserAgentId = "CCDBDownloader";
252 void setupInternalUVLoop();
253
257 int mHandlesInUse = 0;
258
262 CURLM* mCurlMultiHandle = nullptr;
263
267 uv_timer_t* mTimeoutTimer;
268
272 std::vector<CURL*> mHandlesToBeAdded;
273
277 enum RequestType {
278 BLOCKING,
279 ASYNCHRONOUS
280 };
281
285 typedef struct curl_context_s {
286 uv_poll_t* poll_handle;
287 curl_socket_t sockfd = -1;
288 CCDBDownloader* CD = nullptr;
289 } curl_context_t;
290
294 typedef struct DataForSocket {
295 CCDBDownloader* CD;
296 CURLM* curlm;
297 } DataForSocket;
298
299 DataForSocket mSocketData;
300
301#if !defined(__CINT__) && !defined(__MAKECINT__) && !defined(__ROOTCLING__) && !defined(__CLING__)
305 typedef struct PerformData {
306 CURLcode* codeDestination;
307 size_t* requestsLeft;
308 RequestType type;
309 int hostInd;
310 int locInd;
311 DownloaderRequestData* requestData;
312 // Freed by transferFinished; indexed by hostInd, see DownloaderRequestData.
313 std::vector<curl_slist*>* options;
314 } PerformData;
315#endif
316
323 static void closesocketCallback(void* clientp, curl_socket_t item);
324
325#if !defined(__CINT__) && !defined(__MAKECINT__) && !defined(__ROOTCLING__) && !defined(__CLING__)
326 // Returns a new location string or an empty string if all locations under current host have been accessedd
327 std::string getNewLocation(PerformData* performData, std::vector<std::string>& locations) const;
328
329 // Reschedules the transfer to be performed with a different host.
330 void tryNewHost(PerformData* performData, CURL* easy_handle);
331
332 // Retrieves content from either alien, cvmfs or local storage using a callback to CCDBApi.
333 void getLocalContent(PerformData* performData, std::string& newLocation, bool& contentRetrieved, std::vector<std::string>& locations);
334
335 // Continues a transfer via a http redirect.
336 void httpRedirect(PerformData* performData, std::string& newLocation, CURL* easy_handle);
337
338 // Continues a transfer via a redirect. The redirect can point to a local file, alien file or a http address.
339 void followRedirect(PerformData* performData, CURL* easy_handle, std::vector<std::string>& locations, bool& rescheduled, bool& contentRetrieved);
340#endif
341
349 static void curlPerform(uv_poll_t* handle, int status, int events);
350
354 static int handleSocket(CURL* easy, curl_socket_t s, int action, void* userp, void* socketp);
355
361 static void closeSocketByTimer(uv_timer_t* handle);
362
368 static void curlTimeout(uv_timer_t* req);
369
375 static void curlCloseCB(uv_handle_t* handle);
376
382 static void destroyCurlContext(curl_context_t* context);
383
391 static int startTimeout(CURLM* multi, long timeout_ms, void* userp);
392
396 void initializeMultiHandle();
397
404 void transferFinished(CURL* handle, CURLcode curlCode);
405
409 void checkMultiInfo();
410
411#if !defined(__CINT__) && !defined(__MAKECINT__) && !defined(__ROOTCLING__) && !defined(__CLING__)
415 void setHandleOptions(CURL* handle, PerformData* data);
416#endif
417
423 curl_context_t* createCurlContext(curl_socket_t sockfd);
424
428 void checkHandleQueue();
429};
430
434typedef struct DataForClosingSocket {
436 curl_socket_t socket;
437} DataForClosingSocket;
438
439} // namespace o2::ccdb
440
441#endif // O2_CCDB_CCDBDOWNLOADER_H
struct uv_timer_s uv_timer_t
struct uv_signal_s uv_signal_t
struct uv_async_s uv_async_t
struct uv_handle_s uv_handle_t
struct uv_poll_s uv_poll_t
struct uv_loop_s uv_loop_t
Timeframe settings Average distance in cm of events merged into Randomize distance around average distance of merged events Simulate correct bunch interactions instead of placing only the average number of events A value[n] sets TFlen for[n] collisions in Number of bunches per trainsort Number of bunch trains Instantaneous interaction rate Do not simulate border Total number of collisions to be placed in the interior of all time Do not select random but walk over array of events in stride steps h Event generator settings h configStandalone Use CPU for GPU Force usage of the specified GPU device no CPU fallback Continue processing after an error First event to Number of events to Number of iterations to Number of iterations to Number of initial iterations excluded from const char events
Timeframe settings Average distance in cm of events merged into Randomize distance around average distance of merged events Simulate correct bunch interactions instead of placing only the average number of events A value[n] sets TFlen for[n] collisions in Number of bunches per trainsort Number of bunch trains Instantaneous interaction rate Do not simulate border Total number of collisions to be placed in the interior of all time Do not select random but walk over array of events in stride steps h Event generator settings h configStandalone Use CPU for GPU Force usage of the specified GPU device no CPU fallback Continue processing after an error s
CURL * handle
void setRequestTimeoutTime(int timeoutMS)
CURLcode perform(CURL *handle)
void asynchSchedule(CURL *handle, size_t *requestCounter)
std::string trimHostUrl(std::string full_host_url) const
void setKeepaliveTimeoutTime(int timeoutMS)
std::vector< CURLcode > batchBlockingPerform(std::vector< CURL * > const &handleVector)
void setConnectionTimeoutTime(int timeoutMS)
void setHappyEyeballsHeadstartTime(int headstartMS)
std::string prepareLogMessage(std::string host_url, std::string userAgent, const std::string &path, long ts, const std::map< std::string, std::string > *headers, long httpCode) const
std::unordered_map< uv_handle_t *, bool > mHandleMap
std::unordered_map< curl_socket_t, uv_timer_t * > mSocketTimerMap
void setMaxParallelConnections(int limit)
GLuint const GLint * locations
Definition glcorearb.h:5740
GLuint GLuint64EXT address
Definition glcorearb.h:5846
GLint GLint GLsizei GLint GLenum GLenum type
Definition glcorearb.h:275
GLsizei const GLchar *const * path
Definition glcorearb.h:3591
information complementary to a CCDB object (path, metadata, startTimeValidity, endTimeValidity etc)
void closeHandles(uv_handle_t *handle, void *arg)
curl_socket_t opensocketCallback(void *clientp, curlsocktype purpose, struct curl_sockaddr *address)
void onUVClose(uv_handle_t *handle)
std::vector< T, fair::mq::pmr::polymorphic_allocator< T > > vector
std::function< bool(std::string)> localContentCallback
std::vector< curl_slist * > optionsLists
std::vector< std::string > locations
std::vector< std::string > hosts
std::map< std::string, std::string > * headers
std::multimap< std::string, std::string > header