-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added a connectin pool for the sync HTTP client
- Loading branch information
1 parent
1938e8a
commit 4437e05
Showing
5 changed files
with
182 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
/* | ||
* LSST Data Management System | ||
* | ||
* This product includes software developed by the | ||
* LSST Project (http://www.lsst.org/). | ||
* | ||
* This program is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation, either version 3 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the LSST License Statement and | ||
* the GNU General Public License along with this program. If not, | ||
* see <http://www.lsstcorp.org/LegalNotices/>. | ||
*/ | ||
|
||
// Class header | ||
#include "http/ClientConnPool.h" | ||
|
||
// Qserv headers | ||
#include "http/Exceptions.h" | ||
|
||
// Standard headers | ||
#include <cassert> | ||
|
||
using namespace std; | ||
|
||
namespace lsst::qserv::http { | ||
|
||
mutex ClientConnPool::_accessShareCurlMtx; | ||
|
||
ClientConnPool::ClientConnPool(long maxConnections) : _maxConnections(maxConnections) { | ||
_shareCurl = curl_share_init(); | ||
assert(_shareCurl != nullptr); | ||
_errorChecked("curl_share_setopt(CURLSHOPT_LOCKFUNC)", | ||
curl_share_setopt(_shareCurl, CURLSHOPT_LOCKFUNC, &ClientConnPool::_share_lock_cb)); | ||
_errorChecked("curl_share_setopt(CURLSHOPT_UNLOCKFUNC)", | ||
curl_share_setopt(_shareCurl, CURLSHOPT_UNLOCKFUNC, &ClientConnPool::_share_unlock_cb)); | ||
_errorChecked("curl_share_setopt(CURLSHOPT_SHARE, CURL_LOCK_DATA_CONNECT)", | ||
curl_share_setopt(_shareCurl, CURLSHOPT_SHARE, CURL_LOCK_DATA_CONNECT)); | ||
} | ||
|
||
ClientConnPool::~ClientConnPool() { curl_share_cleanup(_shareCurl); } | ||
|
||
void ClientConnPool::_share_lock_cb(CURL* handle, curl_lock_data data, curl_lock_access access, | ||
void* userptr) { | ||
ClientConnPool::_accessShareCurlMtx.lock(); | ||
} | ||
|
||
void ClientConnPool::_share_unlock_cb(CURL* handle, curl_lock_data data, curl_lock_access access, | ||
void* userptr) { | ||
ClientConnPool::_accessShareCurlMtx.unlock(); | ||
} | ||
|
||
void ClientConnPool::_errorChecked(string const& scope, CURLSHcode errnum) { | ||
if (errnum != CURLSHE_OK) { | ||
string const errorStr = curl_share_strerror(errnum); | ||
long const httpResponseCode = 0; | ||
http::raiseRetryAllowedError(scope, " error: '" + errorStr + "', errnum: " + to_string(errnum), | ||
httpResponseCode); | ||
} | ||
} | ||
|
||
} // namespace lsst::qserv::http |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
/* | ||
* LSST Data Management System | ||
* | ||
* This product includes software developed by the | ||
* LSST Project (http://www.lsst.org/). | ||
* | ||
* This program is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation, either version 3 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the LSST License Statement and | ||
* the GNU General Public License along with this program. If not, | ||
* see <http://www.lsstcorp.org/LegalNotices/>. | ||
*/ | ||
#ifndef LSST_QSERV_HTTP_CLIENTCONNPOOL_H | ||
#define LSST_QSERV_HTTP_CLIENTCONNPOOL_H | ||
|
||
// System headers | ||
#include <mutex> | ||
#include <string> | ||
|
||
// Third-party headers | ||
#include "curl/curl.h" | ||
|
||
// This header declarations | ||
namespace lsst::qserv::http { | ||
/** | ||
* Class ClientConnPool is a helper class utilizing the libcurl's context | ||
* sharing mechanism for building a configurable pool of the TCP connections. | ||
* Note that this implementation doesn't directly manage connections. The connections | ||
* are owned and managed by the library itself. A role of the class is to provide | ||
* a synchronization context for acquring/releasing these connections in the multi-thread | ||
* environment. | ||
* | ||
* The implementation is based on: https://curl.se/libcurl/c/libcurl-share.html | ||
*/ | ||
class ClientConnPool { | ||
public: | ||
/** | ||
* Initialize the pool | ||
* @param maxConnections The maximum number of connections alloqwed in the pool. | ||
*/ | ||
explicit ClientConnPool(long maxConnections = 0); | ||
ClientConnPool(ClientConnPool const&) = delete; | ||
ClientConnPool& operator=(ClientConnPool const&) = delete; | ||
|
||
~ClientConnPool(); | ||
|
||
long maxConnections() const { return _maxConnections; } | ||
CURLSH* shareCurl() { return _shareCurl; } | ||
|
||
private: | ||
// These callback functions are required by libcurl to allow easy-based instances | ||
// of the class Client acquire/release connections from the pool. | ||
|
||
static void _share_lock_cb(CURL* handle, curl_lock_data data, curl_lock_access access, void* userptr); | ||
static void _share_unlock_cb(CURL* handle, curl_lock_data data, curl_lock_access access, void* userptr); | ||
|
||
/** | ||
* Check for an error condition. | ||
* | ||
* @param scope A location from which the method was called (used for error reporting). | ||
* @param errnum A result reported by the CURL library function. | ||
* @throw std::runtime_error If the error-code is not CURLSHE_OK. | ||
*/ | ||
void _errorChecked(std::string const& scope, CURLSHcode errnum); | ||
|
||
/// The miutex is shared by all instances of the pool. | ||
static std::mutex _accessShareCurlMtx; | ||
|
||
long const _maxConnections = 0; | ||
CURLSH* _shareCurl; | ||
}; | ||
|
||
} // namespace lsst::qserv::http | ||
|
||
#endif // LSST_QSERV_HTTP_CLIENTCONNPOOL_H |