Skip to content

Commit 4845f82

Browse files
committed
Merge remote-tracking branch 'origin/dev' into stable-sync
2 parents 67059d1 + 42bd8ba commit 4845f82

File tree

193 files changed

+3140
-1061
lines changed

Some content is hidden

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

193 files changed

+3140
-1061
lines changed

Algorithm/test/pageparser.cxx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ struct ClusterData {
5050
{
5151
}
5252

53-
bool operator==(const ClusterData& rhs)
53+
bool operator==(const ClusterData& rhs) const
5454
{
5555
return clusterid == rhs.clusterid && x == rhs.x && y == rhs.y && z == rhs.z && e == rhs.e;
5656
}

CCDB/include/CCDB/CCDBDownloader.h

Lines changed: 76 additions & 8 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;
@@ -32,6 +38,25 @@ typedef struct uv_handle_s uv_handle_t;
3238
namespace o2::ccdb
3339
{
3440

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+
3560
/*
3661
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.
3762
Because non-static functions are used in the functions below, they must be non-member.
@@ -133,6 +158,14 @@ class CCDBDownloader
133158
*/
134159
std::vector<CURLcode> batchBlockingPerform(std::vector<CURL*> const& handleVector);
135160

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+
136169
/**
137170
* Limits the number of parallel connections. Should be used only if no transfers are happening.
138171
*/
@@ -176,6 +209,24 @@ class CCDBDownloader
176209
void runLoop(bool noWait);
177210

178211
private:
212+
/**
213+
* Leaves only the protocol and host part of the url, discrading path and metadata.
214+
*/
215+
std::string trimHostUrl(std::string full_host_url) const;
216+
217+
/**
218+
* Recognizes whether the address is a full url, or a partial one (like for example "/Task/Detector/1") and combines it with potentialHost if needed.
219+
*/
220+
std::string prepareRedirectedURL(std::string address, std::string potentialHost) const;
221+
222+
/**
223+
* Returns a vector of possible content locations based on the redirect headers.
224+
*
225+
* @param baseUrl Content path.
226+
* @param headerMap Map containing response headers.
227+
*/
228+
std::vector<std::string> getLocations(std::multimap<std::string, std::string>* headerMap) const;
229+
179230
std::string mUserAgentId = "CCDBDownloader";
180231
/**
181232
* Sets up internal UV loop.
@@ -207,8 +258,7 @@ class CCDBDownloader
207258
*/
208259
enum RequestType {
209260
BLOCKING,
210-
ASYNCHRONOUS,
211-
ASYNCHRONOUS_WITH_CALLBACK
261+
ASYNCHRONOUS
212262
};
213263

214264
/**
@@ -230,20 +280,19 @@ class CCDBDownloader
230280

231281
DataForSocket mSocketData;
232282

283+
#if !defined(__CINT__) && !defined(__MAKECINT__) && !defined(__ROOTCLING__) && !defined(__CLING__)
233284
/**
234285
* Structure which is stored in a easy_handle. It carries information about the request which the easy_handle is part of.
235-
* All easy handles coming from one request have an identical PerformData structure.
236286
*/
237287
typedef struct PerformData {
238-
std::condition_variable* cv;
239-
bool* completionFlag;
240288
CURLcode* codeDestination;
241-
void (*cbFun)(void*);
242-
std::thread* cbThread;
243-
void* cbData;
244289
size_t* requestsLeft;
245290
RequestType type;
291+
int hostInd;
292+
int locInd;
293+
DownloaderRequestData* requestData;
246294
} PerformData;
295+
#endif
247296

248297
/**
249298
* Called by CURL in order to close a socket. It will be called by CURL even if a timeout timer closed the socket beforehand.
@@ -253,6 +302,23 @@ class CCDBDownloader
253302
*/
254303
static void closesocketCallback(void* clientp, curl_socket_t item);
255304

305+
#if !defined(__CINT__) && !defined(__MAKECINT__) && !defined(__ROOTCLING__) && !defined(__CLING__)
306+
// Returns a new location string or an empty string if all locations under current host have been accessedd
307+
std::string getNewLocation(PerformData* performData, std::vector<std::string>& locations) const;
308+
309+
// Reschedules the transfer to be performed with a different host.
310+
void tryNewHost(PerformData* performData, CURL* easy_handle);
311+
312+
// Retrieves content from either alien, cvmfs or local storage using a callback to CCDBApi.
313+
void getLocalContent(PerformData* performData, std::string& newLocation, bool& contentRetrieved, std::vector<std::string>& locations);
314+
315+
// Continues a transfer via a http redirect.
316+
void httpRedirect(PerformData* performData, std::string& newLocation, CURL* easy_handle);
317+
318+
// Continues a transfer via a redirect. The redirect can point to a local file, alien file or a http address.
319+
void followRedirect(PerformData* performData, CURL* easy_handle, std::vector<std::string>& locations, bool& rescheduled, bool& contentRetrieved);
320+
#endif
321+
256322
/**
257323
* Is used to react to polling file descriptors in poll_handle.
258324
*
@@ -322,10 +388,12 @@ class CCDBDownloader
322388
*/
323389
void checkMultiInfo();
324390

391+
#if !defined(__CINT__) && !defined(__MAKECINT__) && !defined(__ROOTCLING__) && !defined(__CLING__)
325392
/**
326393
* Set openSocketCallback and closeSocketCallback with appropriate arguments. Stores data inside the CURL handle.
327394
*/
328395
void setHandleOptions(CURL* handle, PerformData* data);
396+
#endif
329397

330398
/**
331399
* Create structure holding information about a socket including a poll handle assigned to it

CCDB/include/CCDB/CcdbApi.h

Lines changed: 59 additions & 4 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

@@ -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

@@ -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{};

0 commit comments

Comments
 (0)