Skip to content

Commit 368ab2b

Browse files
wrap AWS SDK lifecycle globals in AwsSdkLifecycle singleton
1 parent aa39102 commit 368ab2b

1 file changed

Lines changed: 64 additions & 39 deletions

File tree

src/iceberg/catalog/rest/auth/sigv4_auth_manager.cc

Lines changed: 64 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -44,17 +44,64 @@ namespace iceberg::rest::auth {
4444

4545
namespace {
4646

47-
enum class LifecycleState : uint8_t { kUninitialized, kInitialized, kFinalized };
47+
class AwsSdkLifecycle {
48+
public:
49+
static AwsSdkLifecycle& Instance() {
50+
static AwsSdkLifecycle instance;
51+
return instance;
52+
}
4853

49-
std::atomic<LifecycleState> g_state{LifecycleState::kUninitialized};
50-
std::mutex g_lifecycle_mutex;
51-
Aws::SDKOptions g_sdk_options;
52-
std::atomic<size_t> g_active_session_count{0};
54+
Status Initialize() {
55+
std::lock_guard<std::mutex> lock(mutex_);
56+
auto s = state_.load();
57+
if (s == State::kInitialized) return {};
58+
if (s == State::kFinalized) {
59+
return InvalidArgument("AWS SDK has already been finalized; cannot reinitialize");
60+
}
61+
Aws::InitAPI(options_);
62+
state_.store(State::kInitialized);
63+
return {};
64+
}
5365

54-
Status EnsureSdkInitialized() {
55-
if (g_state.load() == LifecycleState::kInitialized) return {};
56-
return InitializeAwsSdk();
57-
}
66+
Status Finalize() {
67+
std::lock_guard<std::mutex> lock(mutex_);
68+
if (state_.load() != State::kInitialized) return {};
69+
auto live = active_session_count_.load();
70+
if (live != 0) {
71+
return Invalid(
72+
"Cannot finalize AWS SDK while {} SigV4 auth session(s) are still alive",
73+
live);
74+
}
75+
Aws::ShutdownAPI(options_);
76+
state_.store(State::kFinalized);
77+
return {};
78+
}
79+
80+
Status EnsureInitialized() {
81+
if (state_.load() == State::kInitialized) return {};
82+
return Initialize();
83+
}
84+
85+
bool IsInitialized() const { return state_.load() == State::kInitialized; }
86+
bool IsFinalized() const { return state_.load() == State::kFinalized; }
87+
88+
void IncrementSessionCount() {
89+
active_session_count_.fetch_add(1, std::memory_order_relaxed);
90+
}
91+
void DecrementSessionCount() {
92+
active_session_count_.fetch_sub(1, std::memory_order_relaxed);
93+
}
94+
95+
private:
96+
enum class State : uint8_t { kUninitialized, kInitialized, kFinalized };
97+
98+
AwsSdkLifecycle() = default;
99+
100+
std::atomic<State> state_{State::kUninitialized};
101+
std::mutex mutex_;
102+
Aws::SDKOptions options_;
103+
std::atomic<size_t> active_session_count_{0};
104+
};
58105

59106
Aws::Http::HttpMethod ToAwsMethod(HttpMethod method) {
60107
switch (method) {
@@ -112,12 +159,11 @@ SigV4AuthSession::SigV4AuthSession(
112159
credentials_provider_(std::move(credentials_provider)),
113160
signer_(std::make_unique<RestSigV4Signer>(
114161
credentials_provider_, signing_name_.c_str(), signing_region_.c_str())) {
115-
// Counted so FinalizeAwsSdk() refuses to ShutdownAPI while sessions exist.
116-
g_active_session_count.fetch_add(1, std::memory_order_relaxed);
162+
AwsSdkLifecycle::Instance().IncrementSessionCount();
117163
}
118164

119165
SigV4AuthSession::~SigV4AuthSession() {
120-
g_active_session_count.fetch_sub(1, std::memory_order_relaxed);
166+
AwsSdkLifecycle::Instance().DecrementSessionCount();
121167
}
122168

123169
Result<HttpRequest> SigV4AuthSession::Authenticate(const HttpRequest& request) {
@@ -191,7 +237,7 @@ SigV4AuthManager::~SigV4AuthManager() = default;
191237
Result<std::shared_ptr<AuthSession>> SigV4AuthManager::InitSession(
192238
HttpClient& init_client,
193239
const std::unordered_map<std::string, std::string>& properties) {
194-
ICEBERG_RETURN_UNEXPECTED(EnsureSdkInitialized());
240+
ICEBERG_RETURN_UNEXPECTED(AwsSdkLifecycle::Instance().EnsureInitialized());
195241
ICEBERG_ASSIGN_OR_RAISE(auto delegate_session,
196242
delegate_->InitSession(init_client, properties));
197243
return WrapSession(std::move(delegate_session), properties);
@@ -200,7 +246,7 @@ Result<std::shared_ptr<AuthSession>> SigV4AuthManager::InitSession(
200246
Result<std::shared_ptr<AuthSession>> SigV4AuthManager::CatalogSession(
201247
HttpClient& shared_client,
202248
const std::unordered_map<std::string, std::string>& properties) {
203-
ICEBERG_RETURN_UNEXPECTED(EnsureSdkInitialized());
249+
ICEBERG_RETURN_UNEXPECTED(AwsSdkLifecycle::Instance().EnsureInitialized());
204250
catalog_properties_ = properties;
205251
ICEBERG_ASSIGN_OR_RAISE(auto delegate_session,
206252
delegate_->CatalogSession(shared_client, properties));
@@ -325,34 +371,13 @@ Result<std::unique_ptr<AuthManager>> MakeSigV4AuthManager(
325371
return std::make_unique<SigV4AuthManager>(std::move(delegate));
326372
}
327373

328-
Status InitializeAwsSdk() {
329-
std::lock_guard<std::mutex> lock(g_lifecycle_mutex);
330-
auto state = g_state.load();
331-
if (state == LifecycleState::kInitialized) return {};
332-
if (state == LifecycleState::kFinalized) {
333-
return InvalidArgument("AWS SDK has already been finalized; cannot reinitialize");
334-
}
335-
Aws::InitAPI(g_sdk_options);
336-
g_state.store(LifecycleState::kInitialized);
337-
return {};
338-
}
374+
Status InitializeAwsSdk() { return AwsSdkLifecycle::Instance().Initialize(); }
339375

340-
Status FinalizeAwsSdk() {
341-
std::lock_guard<std::mutex> lock(g_lifecycle_mutex);
342-
if (g_state.load() != LifecycleState::kInitialized) return {};
343-
auto live = g_active_session_count.load();
344-
if (live != 0) {
345-
return Invalid(
346-
"Cannot finalize AWS SDK while {} SigV4 auth session(s) are still alive", live);
347-
}
348-
Aws::ShutdownAPI(g_sdk_options);
349-
g_state.store(LifecycleState::kFinalized);
350-
return {};
351-
}
376+
Status FinalizeAwsSdk() { return AwsSdkLifecycle::Instance().Finalize(); }
352377

353-
bool IsAwsSdkInitialized() { return g_state.load() == LifecycleState::kInitialized; }
378+
bool IsAwsSdkInitialized() { return AwsSdkLifecycle::Instance().IsInitialized(); }
354379

355-
bool IsAwsSdkFinalized() { return g_state.load() == LifecycleState::kFinalized; }
380+
bool IsAwsSdkFinalized() { return AwsSdkLifecycle::Instance().IsFinalized(); }
356381

357382
} // namespace iceberg::rest::auth
358383

0 commit comments

Comments
 (0)