Skip to content

Commit 5708f66

Browse files
committed
Merge remote-tracking branch 'origin/dev' into stable-sync
2 parents b574050 + 3dfca81 commit 5708f66

File tree

506 files changed

+24043
-6657
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

506 files changed

+24043
-6657
lines changed

CCDB/include/CCDB/CCDBDownloader.h

Lines changed: 63 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@
1111
#ifndef O2_CCDBDOWNLOADER_H_
1212
#define O2_CCDBDOWNLOADER_H_
1313

14+
#if !defined(__CINT__) && !defined(__MAKECINT__) && !defined(__ROOTCLING__) && !defined(__CLING__)
15+
#include "MemoryResources/MemoryResources.h"
16+
#endif
17+
1418
#include <cstdio>
1519
#include <cstdlib>
1620
#include <curl/curl.h>
@@ -21,6 +25,8 @@
2125
#include <mutex>
2226
#include <condition_variable>
2327
#include <unordered_map>
28+
#include <map>
29+
#include <functional>
2430

2531
typedef struct uv_loop_s uv_loop_t;
2632
typedef struct uv_timer_s uv_timer_t;
@@ -29,11 +35,28 @@ typedef struct uv_signal_s uv_signal_t;
2935
typedef struct uv_async_s uv_async_t;
3036
typedef struct uv_handle_s uv_handle_t;
3137

32-
using namespace std;
33-
3438
namespace o2::ccdb
3539
{
3640

41+
#if !defined(__CINT__) && !defined(__MAKECINT__) && !defined(__ROOTCLING__) && !defined(__CLING__)
42+
struct HeaderObjectPair_t {
43+
std::multimap<std::string, std::string> header;
44+
o2::pmr::vector<char>* object = nullptr;
45+
int counter = 0;
46+
};
47+
48+
typedef struct DownloaderRequestData {
49+
std::vector<std::string> hosts;
50+
std::string path;
51+
long timestamp;
52+
HeaderObjectPair_t hoPair;
53+
std::map<std::string, std::string>* headers;
54+
55+
std::function<bool(std::string)> localContentCallback;
56+
bool errorflag = false;
57+
} DownloaderRequestData;
58+
#endif
59+
3760
/*
3861
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.
3962
Because non-static functions are used in the functions below, they must be non-member.
@@ -135,6 +158,14 @@ class CCDBDownloader
135158
*/
136159
std::vector<CURLcode> batchBlockingPerform(std::vector<CURL*> const& handleVector);
137160

161+
/**
162+
* Schedules an asynchronous transfer but doesn't perform it.
163+
*
164+
* @param handle Handle to be performed on.
165+
* @param requestCounter Counter shared by a batch of CURL handles.
166+
*/
167+
void asynchSchedule(CURL* handle, size_t* requestCounter);
168+
138169
/**
139170
* Limits the number of parallel connections. Should be used only if no transfers are happening.
140171
*/
@@ -178,6 +209,14 @@ class CCDBDownloader
178209
void runLoop(bool noWait);
179210

180211
private:
212+
/**
213+
* Returns a vector of possible content locations based on the redirect headers.
214+
*
215+
* @param baseUrl Content path.
216+
* @param headerMap Map containing response headers.
217+
*/
218+
std::vector<std::string> getLocations(std::string baseUrl, std::multimap<std::string, std::string>* headerMap) const;
219+
181220
std::string mUserAgentId = "CCDBDownloader";
182221
/**
183222
* Sets up internal UV loop.
@@ -209,8 +248,7 @@ class CCDBDownloader
209248
*/
210249
enum RequestType {
211250
BLOCKING,
212-
ASYNCHRONOUS,
213-
ASYNCHRONOUS_WITH_CALLBACK
251+
ASYNCHRONOUS
214252
};
215253

216254
/**
@@ -232,20 +270,19 @@ class CCDBDownloader
232270

233271
DataForSocket mSocketData;
234272

273+
#if !defined(__CINT__) && !defined(__MAKECINT__) && !defined(__ROOTCLING__) && !defined(__CLING__)
235274
/**
236275
* Structure which is stored in a easy_handle. It carries information about the request which the easy_handle is part of.
237-
* All easy handles coming from one request have an identical PerformData structure.
238276
*/
239277
typedef struct PerformData {
240-
std::condition_variable* cv;
241-
bool* completionFlag;
242278
CURLcode* codeDestination;
243-
void (*cbFun)(void*);
244-
std::thread* cbThread;
245-
void* cbData;
246279
size_t* requestsLeft;
247280
RequestType type;
281+
int hostInd;
282+
int locInd;
283+
DownloaderRequestData* requestData;
248284
} PerformData;
285+
#endif
249286

250287
/**
251288
* Called by CURL in order to close a socket. It will be called by CURL even if a timeout timer closed the socket beforehand.
@@ -255,6 +292,20 @@ class CCDBDownloader
255292
*/
256293
static void closesocketCallback(void* clientp, curl_socket_t item);
257294

295+
#if !defined(__CINT__) && !defined(__MAKECINT__) && !defined(__ROOTCLING__) && !defined(__CLING__)
296+
// Reschedules the transfer to be performed with a different host.
297+
void tryNewHost(PerformData* performData, CURL* easy_handle);
298+
299+
// Retrieves content from either alien, cvmfs or local storage using a callback to CCDBApi.
300+
void getLocalContent(PerformData* performData, std::string& newUrl, std::string& newLocation, bool& contentRetrieved, std::vector<std::string>& locations);
301+
302+
// Continues a transfer via a http redirect.
303+
void httpRedirect(PerformData* performData, std::string& newUrl, std::string& newLocation, CURL* easy_handle);
304+
305+
// Continues a transfer via a redirect. The redirect can point to a local file, alien file or a http address.
306+
void followRedirect(PerformData* performData, CURL* easy_handle, std::vector<std::string>& locations, bool& rescheduled, bool& contentRetrieved);
307+
#endif
308+
258309
/**
259310
* Is used to react to polling file descriptors in poll_handle.
260311
*
@@ -324,10 +375,12 @@ class CCDBDownloader
324375
*/
325376
void checkMultiInfo();
326377

378+
#if !defined(__CINT__) && !defined(__MAKECINT__) && !defined(__ROOTCLING__) && !defined(__CLING__)
327379
/**
328380
* Set openSocketCallback and closeSocketCallback with appropriate arguments. Stores data inside the CURL handle.
329381
*/
330382
void setHandleOptions(CURL* handle, PerformData* data);
383+
#endif
331384

332385
/**
333386
* Create structure holding information about a socket including a poll handle assigned to it

CCDB/include/CCDB/CcdbApi.h

Lines changed: 94 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -24,18 +24,20 @@
2424
#include <TObject.h>
2525
#include <TMessage.h>
2626
#include "CCDB/CcdbObjectInfo.h"
27-
#include "CCDB/CCDBDownloader.h"
2827
#include <CommonUtils/ConfigurableParam.h>
2928
#include <type_traits>
3029
#include <vector>
3130

3231
#if !defined(__CINT__) && !defined(__MAKECINT__) && !defined(__ROOTCLING__) && !defined(__CLING__)
3332
#include "MemoryResources/MemoryResources.h"
33+
#include <boost/interprocess/sync/named_semaphore.hpp>
3434
#include <TJAlienCredentials.h>
3535
#else
3636
class TJAlienCredentials;
3737
#endif
3838

39+
#include "CCDB/CCDBDownloader.h"
40+
3941
class TFile;
4042
class TGrid;
4143

@@ -119,34 +121,34 @@ class CcdbApi //: public DatabaseInterface
119121
static std::unique_ptr<std::vector<char>> createObjectImage(const void* obj, std::type_info const& tinfo, CcdbObjectInfo* info = nullptr);
120122

121123
/**
122-
* Store into the CCDB a TFile containing the ROOT object.
123-
*
124-
* @param rootObject Raw pointer to the object to store.
125-
* @param path The path where the object is going to be stored.
126-
* @param metadata Key-values representing the metadata for this object.
127-
* @param startValidityTimestamp Start of validity. If omitted, current timestamp is used.
128-
* @param endValidityTimestamp End of validity. If omitted, current timestamp + 1 day is used.
129-
* @return 0 -> ok,
130-
* positive number -> curl error (https://curl.se/libcurl/c/libcurl-errors.html),
131-
* -1 : object bigger than maxSize,
132-
* -2 : curl initialization error
133-
*/
124+
* Store into the CCDB a TFile containing the ROOT object.
125+
*
126+
* @param rootObject Raw pointer to the object to store.
127+
* @param path The path where the object is going to be stored.
128+
* @param metadata Key-values representing the metadata for this object.
129+
* @param startValidityTimestamp Start of validity. If omitted, current timestamp is used.
130+
* @param endValidityTimestamp End of validity. If omitted, current timestamp + 1 day is used.
131+
* @return 0 -> ok,
132+
* positive number -> curl error (https://curl.se/libcurl/c/libcurl-errors.html),
133+
* -1 : object bigger than maxSize,
134+
* -2 : curl initialization error
135+
*/
134136
int storeAsTFile(const TObject* rootObject, std::string const& path, std::map<std::string, std::string> const& metadata,
135137
long startValidityTimestamp = -1, long endValidityTimestamp = -1, std::vector<char>::size_type maxSize = 0 /*bytes*/) const;
136138

137139
/**
138-
* Store into the CCDB a TFile containing an object of type T (which needs to have a ROOT dictionary)
139-
*
140-
* @param obj Raw pointer to the object to store.
141-
* @param path The path where the object is going to be stored.
142-
* @param metadata Key-values representing the metadata for this object.
143-
* @param startValidityTimestamp Start of validity. If omitted, current timestamp is used.
144-
* @param endValidityTimestamp End of validity. If omitted, current timestamp + 1 day is used.
145-
* @return 0 -> ok,
146-
* positive number -> curl error (https://curl.se/libcurl/c/libcurl-errors.html),
147-
* -1 : object bigger than maxSize,
148-
* -2 : curl initialization error
149-
*/
140+
* Store into the CCDB a TFile containing an object of type T (which needs to have a ROOT dictionary)
141+
*
142+
* @param obj Raw pointer to the object to store.
143+
* @param path The path where the object is going to be stored.
144+
* @param metadata Key-values representing the metadata for this object.
145+
* @param startValidityTimestamp Start of validity. If omitted, current timestamp is used.
146+
* @param endValidityTimestamp End of validity. If omitted, current timestamp + 1 day is used.
147+
* @return 0 -> ok,
148+
* positive number -> curl error (https://curl.se/libcurl/c/libcurl-errors.html),
149+
* -1 : object bigger than maxSize,
150+
* -2 : curl initialization error
151+
*/
150152
template <typename T>
151153
int storeAsTFileAny(const T* obj, std::string const& path, std::map<std::string, std::string> const& metadata,
152154
long startValidityTimestamp = -1, long endValidityTimestamp = -1, std::vector<char>::size_type maxSize = 0 /*bytes*/) const
@@ -233,7 +235,7 @@ class CcdbApi //: public DatabaseInterface
233235
* @param returnFormat The format of the returned string -> one of "text/plain (default)", "application/json", "text/xml"
234236
* @return The listing of folder and/or objects in the format requested
235237
*/
236-
std::string list(std::string const& path = "", bool latestOnly = false, std::string const& returnFormat = "text/plain") const;
238+
std::string list(std::string const& path = "", bool latestOnly = false, std::string const& returnFormat = "text/plain", long createdNotAfter = -1, long createdNotBefore = -1) const;
237239

238240
/**
239241
* Make a local snapshot of all valid objects, given a timestamp, of the CCDB under a given local path.
@@ -249,12 +251,12 @@ class CcdbApi //: public DatabaseInterface
249251
bool isHostReachable() const;
250252

251253
/**
252-
* Helper function to extract the list of sub-folders from a list reply into a vector container.
253-
* Can be used to achieve full recursive traversal/listing of the CCDB.
254-
*
255-
* @param reply The reply that we got from a GET/browse sort of request.
256-
* @return The vector of sub-folders.
257-
*/
254+
* Helper function to extract the list of sub-folders from a list reply into a vector container.
255+
* Can be used to achieve full recursive traversal/listing of the CCDB.
256+
*
257+
* @param reply The reply that we got from a GET/browse sort of request.
258+
* @return The vector of sub-folders.
259+
*/
258260
std::vector<std::string> parseSubFolders(std::string const& reply) const;
259261

260262
/**
@@ -342,14 +344,43 @@ class CcdbApi //: public DatabaseInterface
342344
TObject* retrieveFromTFile(std::string const& path, std::map<std::string, std::string> const& metadata, long timestamp,
343345
std::map<std::string, std::string>* headers, std::string const& etag,
344346
const std::string& createdNotAfter, const std::string& createdNotBefore) const;
345-
346347
#if !defined(__CINT__) && !defined(__MAKECINT__) && !defined(__ROOTCLING__) && !defined(__CLING__)
348+
typedef struct RequestContext {
349+
o2::pmr::vector<char>& dest;
350+
std::string path;
351+
std::map<std::string, std::string> const& metadata;
352+
long timestamp;
353+
std::map<std::string, std::string>& headers;
354+
std::string etag;
355+
std::string createdNotAfter;
356+
std::string createdNotBefore;
357+
bool considerSnapshot;
358+
359+
RequestContext(o2::pmr::vector<char>& d,
360+
std::map<std::string, std::string> const& m,
361+
std::map<std::string, std::string>& h)
362+
: dest(d), metadata(m), headers(h) {}
363+
} RequestContext;
364+
365+
// Stores file associated with requestContext as a snapshot.
366+
void saveSnapshot(RequestContext& requestContext) const;
367+
368+
// Schedules download via CCDBDownloader, but doesn't perform it until mUVLoop is ran.
369+
void scheduleDownload(RequestContext& requestContext, size_t* requestCounter) const;
370+
371+
void getFromSnapshot(bool createSnapshot, std::string const& path,
372+
long timestamp, std::map<std::string, std::string> headers,
373+
std::string& snapshotpath, o2::pmr::vector<char>& dest, int& fromSnapshot, std::string const& etag) const;
374+
void releaseNamedSemaphore(boost::interprocess::named_semaphore* sem, std::string path) const;
375+
boost::interprocess::named_semaphore* createNamedSempahore(std::string path) const;
347376
void loadFileToMemory(o2::pmr::vector<char>& dest, const std::string& path, std::map<std::string, std::string>* localHeaders = nullptr) const;
348377
void loadFileToMemory(o2::pmr::vector<char>& dest, std::string const& path,
349378
std::map<std::string, std::string> const& metadata, long timestamp,
350379
std::map<std::string, std::string>* headers, std::string const& etag,
351380
const std::string& createdNotAfter, const std::string& createdNotBefore, bool considerSnapshot = true) const;
352-
void navigateURLsAndLoadFileToMemory(o2::pmr::vector<char>& dest, CURL* curl_handle, std::string const& url, std::map<string, string>* headers) const;
381+
382+
// Loads files from alien and cvmfs into given destination.
383+
bool loadLocalContentToMemory(o2::pmr::vector<char>& dest, std::string& url) const;
353384

354385
// the failure to load the file to memory is signaled by 0 size and non-0 capacity
355386
static bool isMemoryFileInvalid(const o2::pmr::vector<char>& v) { return v.size() == 0 && v.capacity() > 0; }
@@ -364,12 +395,36 @@ class CcdbApi //: public DatabaseInterface
364395
}
365396
return obj;
366397
}
398+
399+
/**
400+
* Retrieves files either as snapshot or schedules them to be downloaded via CCDBDownloader.
401+
*
402+
* @param requestContext Structure giving details about the transfer.
403+
* @param fromSnapshot After navigateSourcesAndLoadFile returns signals whether file was retrieved from snapshot.
404+
* @param requestCounter Pointer to the variable storing the number of requests to be done.
405+
*/
406+
void navigateSourcesAndLoadFile(RequestContext& requestContext, int& fromSnapshot, size_t* requestCounter) const;
407+
408+
/**
409+
* Retrieves files described via RequestContexts into memory. Downloads are performed in parallel via CCDBDownloader.
410+
*
411+
* @param requestContext Structure giving details about the transfer.
412+
*/
413+
void vectoredLoadFileToMemory(std::vector<RequestContext>& requestContext) const;
367414
#endif
368415

369416
private:
370417
// Sets the unique agent ID
371418
void setUniqueAgentID();
372419

420+
/**
421+
* Schedules download of data associated with the curl_handle. Doing that increments the requestCounter by 1. Requests are performed by running the mUVLoop
422+
*
423+
* @param handle CURL handle associated with the request.
424+
* @param requestCounter Pointer to the variable storing the number of requests to be done.
425+
*/
426+
void asynchPerform(CURL* handle, size_t* requestCounter) const;
427+
373428
// internal helper function to update a CCDB file with meta information
374429
static void updateMetaInformationInLocalFile(std::string const& filename, std::map<std::string, std::string> const* headers, CCDBQuery const* querysummary = nullptr);
375430

@@ -526,9 +581,9 @@ class CcdbApi //: public DatabaseInterface
526581
const std::string& createdNotAfter, const std::string& createdNotBefore, bool followRedirect, CurlWriteCallback writeCallback) const;
527582

528583
/**
529-
* Initialize hostsPool
530-
* @param hosts string with hosts separated by "," or ";"
531-
*/
584+
* Initialize hostsPool
585+
* @param hosts string with hosts separated by "," or ";"
586+
*/
532587
void initHostsPool(std::string hosts);
533588

534589
std::string getHostUrl(int hostIndex) const;
@@ -550,7 +605,7 @@ class CcdbApi //: public DatabaseInterface
550605
CURLcode CURL_perform(CURL* handle) const;
551606

552607
mutable CCDBDownloader* mDownloader = nullptr; //! the multi-handle (async) CURL downloader
553-
bool mIsCCDBDownloaderEnabled = false;
608+
bool mIsCCDBDownloaderPreferred = false;
554609
/// Base URL of the CCDB (with port)
555610
std::string mUniqueAgentID{}; // Unique User-Agent ID communicated to server for logging
556611
std::string mUrl{};
@@ -595,4 +650,4 @@ typename std::enable_if<std::is_base_of<o2::conf::ConfigurableParam, T>::value,
595650
} // namespace ccdb
596651
} // namespace o2
597652

598-
#endif //PROJECT_CCDBAPI_H
653+
#endif // PROJECT_CCDBAPI_H

0 commit comments

Comments
 (0)