| #include "http_client_pool.h" |
| |
| #include <cstddef> |
| #include <memory> |
| #include <stack> |
| #include <utility> |
| |
| #include "absl/base/thread_annotations.h" |
| #include "absl/functional/any_invocable.h" |
| #include "absl/log/log.h" |
| #include "absl/synchronization/mutex.h" |
| #include "redfish_query_engine/http/client.h" |
| |
| namespace milotic { |
| |
| HttpClientPool::HttpClientPool( |
| absl::AnyInvocable<std::unique_ptr<ecclesia::HttpClient>()> client_factory, |
| const Config& config) |
| : acquire_client_timeout_(config.acquire_client_timeout) { |
| for (size_t i = 0; i < config.max_concurrent_requests; ++i) { |
| clients_.push(client_factory()); |
| } |
| } |
| |
| std::unique_ptr<ecclesia::HttpClient> HttpClientPool::GetClient() { |
| auto cond = [this]() ABSL_SHARED_LOCKS_REQUIRED(mutex_) { |
| return !clients_.empty(); |
| }; |
| absl::MutexLock lock(&mutex_); |
| if (!mutex_.AwaitWithTimeout(absl::Condition(&cond), |
| acquire_client_timeout_)) { |
| LOG(ERROR) << "Timed out waiting for a client to be available."; |
| return nullptr; |
| } |
| std::unique_ptr<ecclesia::HttpClient> client = std::move(clients_.top()); |
| clients_.pop(); |
| return client; |
| } |
| |
| void HttpClientPool::ReturnClient( |
| std::unique_ptr<ecclesia::HttpClient> client) { |
| absl::MutexLock lock(&mutex_); |
| clients_.push(std::move(client)); |
| } |
| |
| } // namespace milotic |