1212#include < CCDB/CCDBDownloader.h>
1313#include " CommonUtils/StringUtils.h"
1414#include " CCDB/CCDBTimeStampUtils.h"
15+ #include " Framework/Signpost.h"
1516
1617#include < curl/curl.h>
1718#include < unordered_map>
2930#include < fairlogger/Logger.h>
3031#include < boost/asio/ip/host_name.hpp>
3132
33+ O2_DECLARE_DYNAMIC_STACKTRACE_LOG (ccdb_downloader);
34+
3235namespace o2 ::ccdb
3336{
3437
35- void uvErrorCheck (int code)
38+ void uvErrorCheck (int code, DownloaderErrorLevel level )
3639{
3740 if (code != 0 ) {
3841 char buf[1000 ];
3942 uv_strerror_r (code, buf, 1000 );
40- LOG (error) << " CCDBDownloader: UV error - " << buf;
43+ O2_SIGNPOST_ID_GENERATE (sid, ccdb_downloader);
44+ if (level == SEVERE) {
45+ O2_SIGNPOST_EVENT_EMIT_ERROR (ccdb_downloader, sid, " CCDBDownloader" , " UV error - %{public}s" , buf);
46+ } else {
47+ O2_SIGNPOST_EVENT_EMIT_WARN (ccdb_downloader, sid, " CCDBDownloader" , " UV minor error - %{public}s" , buf);
48+ }
4149 }
4250}
4351
4452void curlEasyErrorCheck (CURLcode code)
4553{
4654 if (code != CURLE_OK) {
47- LOG (error) << " CCDBDownloader: CURL error - " << curl_easy_strerror (code);
55+ O2_SIGNPOST_ID_GENERATE (sid, ccdb_downloader);
56+ O2_SIGNPOST_EVENT_EMIT_ERROR (ccdb_downloader, sid, " CCDBDownloader" , " CURL error - %{public}s" , curl_easy_strerror (code));
4857 }
4958}
5059
5160void curlMultiErrorCheck (CURLMcode code)
5261{
5362 if (code != CURLM_OK) {
54- LOG (error) << " CCDBDownloader: CURL error - " << curl_multi_strerror (code);
63+ O2_SIGNPOST_ID_GENERATE (sid, ccdb_downloader);
64+ O2_SIGNPOST_EVENT_EMIT_ERROR (ccdb_downloader, sid, " CCDBDownloader" , " CURL error - %{public}s" , curl_multi_strerror (code));
5565 }
5666}
5767namespace
@@ -80,9 +90,9 @@ CCDBDownloader::CCDBDownloader(uv_loop_t* uv_loop)
8090 }
8191
8292 // Preparing timer to be used by curl
83- mTimeoutTimer = new uv_timer_t ( );
93+ mTimeoutTimer = ( uv_timer_t *) malloc ( sizeof (* mTimeoutTimer ) );
8494 mTimeoutTimer ->data = this ;
85- uvErrorCheck (uv_timer_init (mUVLoop , mTimeoutTimer ));
95+ uvErrorCheck (uv_timer_init (mUVLoop , mTimeoutTimer ), SEVERE );
8696 mHandleMap [(uv_handle_t *)mTimeoutTimer ] = true ;
8797
8898 initializeMultiHandle ();
@@ -91,7 +101,7 @@ CCDBDownloader::CCDBDownloader(uv_loop_t* uv_loop)
91101void CCDBDownloader::setupInternalUVLoop ()
92102{
93103 mUVLoop = new uv_loop_t ();
94- uvErrorCheck (uv_loop_init (mUVLoop ));
104+ uvErrorCheck (uv_loop_init (mUVLoop ), SEVERE );
95105}
96106
97107void CCDBDownloader::initializeMultiHandle ()
@@ -114,7 +124,7 @@ CCDBDownloader::~CCDBDownloader()
114124
115125 if (!mExternalLoop ) {
116126 // Schedule all handles to close. Execute loop to allow them to execute their destructors.
117- while (uv_loop_alive (mUVLoop ) && uv_loop_close (mUVLoop ) == UV_EBUSY) {
127+ while (uv_loop_alive (mUVLoop ) || ( uv_loop_close (mUVLoop ) == UV_EBUSY) ) {
118128 uv_walk (mUVLoop , closeHandles, this );
119129 uv_run (mUVLoop , UV_RUN_ONCE);
120130 }
@@ -136,7 +146,7 @@ void closeHandles(uv_handle_t* handle, void* arg)
136146void onUVClose (uv_handle_t * handle)
137147{
138148 if (handle != nullptr ) {
139- delete handle;
149+ free ( handle) ;
140150 }
141151}
142152
@@ -147,20 +157,22 @@ void CCDBDownloader::closesocketCallback(void* clientp, curl_socket_t item)
147157 // If external uv loop is used then the keepalive mechanism is active.
148158 if (CD->mSocketTimerMap .find (item) != CD->mSocketTimerMap .end ()) {
149159 auto timer = CD->mSocketTimerMap [item];
150- uvErrorCheck (uv_timer_stop (timer));
160+ uvErrorCheck (uv_timer_stop (timer), SEVERE );
151161 // we are getting rid of the uv_timer_t pointer ... so we need
152162 // to free possibly attached user data pointers as well. Counteracts action of opensocketCallback
153163 if (timer->data ) {
154164 delete (DataForClosingSocket*)timer->data ;
155165 }
156166 CD->mSocketTimerMap .erase (item);
157167 if (close (item) == -1 ) {
158- LOG (error) << " CCDBDownloader: Socket failed to close" ;
168+ O2_SIGNPOST_ID_GENERATE (sid, ccdb_downloader);
169+ O2_SIGNPOST_EVENT_EMIT_ERROR (ccdb_downloader, sid, " CCDBDownloader" , " CCDBDownloader: Socket failed to close" );
159170 }
160171 }
161172 } else {
162173 if (close (item) == -1 ) {
163- LOG (error) << " CCDBDownloader: Socket failed to close" ;
174+ O2_SIGNPOST_ID_GENERATE (sid, ccdb_downloader);
175+ O2_SIGNPOST_EVENT_EMIT_ERROR (ccdb_downloader, sid, " CCDBDownloader" , " CCDBDownloader: Socket failed to close" );
164176 }
165177 }
166178}
@@ -170,12 +182,13 @@ curl_socket_t opensocketCallback(void* clientp, curlsocktype purpose, struct cur
170182 auto CD = (CCDBDownloader*)clientp;
171183 auto sock = socket (address->family , address->socktype , address->protocol );
172184 if (sock == -1 ) {
173- LOG (error) << " CCDBDownloader: Socket failed to open" ;
185+ O2_SIGNPOST_ID_GENERATE (sid, ccdb_downloader);
186+ O2_SIGNPOST_EVENT_EMIT_ERROR (ccdb_downloader, sid, " CCDBDownloader" , " CCDBDownloader: Socket failed to open" );
174187 }
175188
176189 if (CD->mExternalLoop ) {
177- CD->mSocketTimerMap [sock] = new uv_timer_t ( );
178- uvErrorCheck (uv_timer_init (CD->mUVLoop , CD->mSocketTimerMap [sock]));
190+ CD->mSocketTimerMap [sock] = ( uv_timer_t *) malloc ( sizeof (*CD-> mSocketTimerMap [sock]) );
191+ uvErrorCheck (uv_timer_init (CD->mUVLoop , CD->mSocketTimerMap [sock]), SEVERE );
179192 CD->mHandleMap [(uv_handle_t *)CD->mSocketTimerMap [sock]] = true ;
180193
181194 auto data = new DataForClosingSocket ();
@@ -194,10 +207,11 @@ void CCDBDownloader::closeSocketByTimer(uv_timer_t* handle)
194207 auto sock = data->socket ;
195208
196209 if (CD->mSocketTimerMap .find (sock) != CD->mSocketTimerMap .end ()) {
197- uvErrorCheck (uv_timer_stop (CD->mSocketTimerMap [sock]));
210+ uvErrorCheck (uv_timer_stop (CD->mSocketTimerMap [sock]), SEVERE );
198211 CD->mSocketTimerMap .erase (sock);
199212 if (close (sock) == -1 ) {
200- LOG (error) << " CCDBDownloader: Socket failed to close" ;
213+ O2_SIGNPOST_ID_GENERATE (sid, ccdb_downloader);
214+ O2_SIGNPOST_EVENT_EMIT_ERROR (ccdb_downloader, sid, " CCDBDownloader" , " CCDBDownloader: Socket failed to close" );
201215 }
202216 delete data;
203217 }
@@ -213,7 +227,7 @@ void CCDBDownloader::curlTimeout(uv_timer_t* handle)
213227
214228void CCDBDownloader::curlPerform (uv_poll_t * handle, int status, int events)
215229{
216- uvErrorCheck (status);
230+ uvErrorCheck (status, MINOR );
217231 int running_handles;
218232 int flags = 0 ;
219233 if (events & UV_READABLE) {
@@ -252,20 +266,20 @@ int CCDBDownloader::handleSocket(CURL* easy, curl_socket_t s, int action, void*
252266 }
253267
254268 if (CD->mExternalLoop && CD->mSocketTimerMap .find (s) != CD->mSocketTimerMap .end ()) {
255- uvErrorCheck (uv_timer_stop (CD->mSocketTimerMap [s]));
269+ uvErrorCheck (uv_timer_stop (CD->mSocketTimerMap [s]), SEVERE );
256270 }
257271
258- uvErrorCheck (uv_poll_start (curl_context->poll_handle , events, curlPerform));
272+ uvErrorCheck (uv_poll_start (curl_context->poll_handle , events, curlPerform), SEVERE );
259273 break ;
260274 case CURL_POLL_REMOVE:
261275 if (socketp) {
262276 if (CD->mExternalLoop ) {
263277 // If external loop is used then start the keepalive timeout.
264278 if (CD->mSocketTimerMap .find (s) != CD->mSocketTimerMap .end ()) {
265- uvErrorCheck (uv_timer_start (CD->mSocketTimerMap [s], closeSocketByTimer, CD->mKeepaliveTimeoutMS , 0 ));
279+ uvErrorCheck (uv_timer_start (CD->mSocketTimerMap [s], closeSocketByTimer, CD->mKeepaliveTimeoutMS , 0 ), SEVERE );
266280 }
267281 }
268- uvErrorCheck (uv_poll_stop (((CCDBDownloader::curl_context_t *)socketp)->poll_handle ));
282+ uvErrorCheck (uv_poll_stop (((CCDBDownloader::curl_context_t *)socketp)->poll_handle ), SEVERE );
269283 CD->destroyCurlContext ((CCDBDownloader::curl_context_t *)socketp);
270284 curlMultiErrorCheck (curl_multi_assign (socketData->curlm , s, nullptr ));
271285 }
@@ -323,9 +337,9 @@ CCDBDownloader::curl_context_t* CCDBDownloader::createCurlContext(curl_socket_t
323337 context = (curl_context_t *)malloc (sizeof (*context));
324338 context->CD = this ;
325339 context->sockfd = sockfd;
326- context->poll_handle = new uv_poll_t ( );
340+ context->poll_handle = ( uv_poll_t *) malloc ( sizeof (*context-> poll_handle ) );
327341
328- uvErrorCheck (uv_poll_init_socket (mUVLoop , context->poll_handle , sockfd));
342+ uvErrorCheck (uv_poll_init_socket (mUVLoop , context->poll_handle , sockfd), SEVERE );
329343 mHandleMap [(uv_handle_t *)(context->poll_handle )] = true ;
330344 context->poll_handle ->data = context;
331345
@@ -335,7 +349,7 @@ CCDBDownloader::curl_context_t* CCDBDownloader::createCurlContext(curl_socket_t
335349void CCDBDownloader::curlCloseCB (uv_handle_t * handle)
336350{
337351 auto * context = (curl_context_t *)handle->data ;
338- delete context->poll_handle ;
352+ free ( context->poll_handle ) ;
339353 free (context);
340354}
341355
@@ -470,6 +484,10 @@ void CCDBDownloader::transferFinished(CURL* easy_handle, CURLcode curlCode)
470484 bool rescheduled = false ;
471485 bool contentRetrieved = false ;
472486
487+ if (curlCode != 0 ) {
488+ LOG (error) << " CCDBDownloader CURL transfer error - " << curl_easy_strerror (curlCode) << " \n " ;
489+ }
490+
473491 switch (performData->type ) {
474492 case BLOCKING: {
475493 --(*performData->requestsLeft );
@@ -502,12 +520,17 @@ void CCDBDownloader::transferFinished(CURL* easy_handle, CURLcode curlCode)
502520 } else if (300 <= httpCode && httpCode < 400 && performData->locInd < locations.size ()) {
503521 followRedirect (performData, easy_handle, locations, rescheduled, contentRetrieved);
504522 } else if (200 <= httpCode && httpCode < 300 ) {
505- contentRetrieved = true ;
523+ contentRetrieved = true ; // Can be overruled by following error check
506524 }
507525 } else {
508526 LOG (error) << loggingMessage;
509527 }
510528
529+ // Check for errors
530+ if (curlCode != 0 ) {
531+ contentRetrieved = false ;
532+ }
533+
511534 // Check if content was retrieved, or scheduled to be retrieved
512535 if (!rescheduled && !contentRetrieved && performData->locInd == locations.size ()) {
513536 // Ran out of locations to redirect, try new host
@@ -579,12 +602,12 @@ int CCDBDownloader::startTimeout(CURLM* multi, long timeout_ms, void* userp)
579602 auto timeout = (uv_timer_t *)userp;
580603
581604 if (timeout_ms < 0 ) {
582- uvErrorCheck (uv_timer_stop (timeout));
605+ uvErrorCheck (uv_timer_stop (timeout), SEVERE );
583606 } else {
584607 if (timeout_ms == 0 ) {
585608 timeout_ms = 1 ; // Calling curlTimeout when timeout = 0 could create an infinite loop
586609 }
587- uvErrorCheck (uv_timer_start (timeout, curlTimeout, timeout_ms, 0 ));
610+ uvErrorCheck (uv_timer_start (timeout, curlTimeout, timeout_ms, 0 ), SEVERE );
588611 }
589612 return 0 ;
590613}
0 commit comments