Skip to content

Commit 8aea28c

Browse files
wrap AWS SDK lifecycle globals in AwsSdkLifecycle singleton
1 parent aa39102 commit 8aea28c

1 file changed

Lines changed: 63 additions & 39 deletions

File tree

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

Lines changed: 63 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -44,17 +44,63 @@ 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", live);
73+
}
74+
Aws::ShutdownAPI(options_);
75+
state_.store(State::kFinalized);
76+
return {};
77+
}
78+
79+
Status EnsureInitialized() {
80+
if (state_.load() == State::kInitialized) return {};
81+
return Initialize();
82+
}
83+
84+
bool IsInitialized() const { return state_.load() == State::kInitialized; }
85+
bool IsFinalized() const { return state_.load() == State::kFinalized; }
86+
87+
void IncrementSessionCount() {
88+
active_session_count_.fetch_add(1, std::memory_order_relaxed);
89+
}
90+
void DecrementSessionCount() {
91+
active_session_count_.fetch_sub(1, std::memory_order_relaxed);
92+
}
93+
94+
private:
95+
enum class State : uint8_t { kUninitialized, kInitialized, kFinalized };
96+
97+
AwsSdkLifecycle() = default;
98+
99+
std::atomic<State> state_{State::kUninitialized};
100+
std::mutex mutex_;
101+
Aws::SDKOptions options_;
102+
std::atomic<size_t> active_session_count_{0};
103+
};
58104

59105
Aws::Http::HttpMethod ToAwsMethod(HttpMethod method) {
60106
switch (method) {
@@ -112,12 +158,11 @@ SigV4AuthSession::SigV4AuthSession(
112158
credentials_provider_(std::move(credentials_provider)),
113159
signer_(std::make_unique<RestSigV4Signer>(
114160
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);
161+
AwsSdkLifecycle::Instance().IncrementSessionCount();
117162
}
118163

119164
SigV4AuthSession::~SigV4AuthSession() {
120-
g_active_session_count.fetch_sub(1, std::memory_order_relaxed);
165+
AwsSdkLifecycle::Instance().DecrementSessionCount();
121166
}
122167

123168
Result<HttpRequest> SigV4AuthSession::Authenticate(const HttpRequest& request) {
@@ -191,7 +236,7 @@ SigV4AuthManager::~SigV4AuthManager() = default;
191236
Result<std::shared_ptr<AuthSession>> SigV4AuthManager::InitSession(
192237
HttpClient& init_client,
193238
const std::unordered_map<std::string, std::string>& properties) {
194-
ICEBERG_RETURN_UNEXPECTED(EnsureSdkInitialized());
239+
ICEBERG_RETURN_UNEXPECTED(AwsSdkLifecycle::Instance().EnsureInitialized());
195240
ICEBERG_ASSIGN_OR_RAISE(auto delegate_session,
196241
delegate_->InitSession(init_client, properties));
197242
return WrapSession(std::move(delegate_session), properties);
@@ -200,7 +245,7 @@ Result<std::shared_ptr<AuthSession>> SigV4AuthManager::InitSession(
200245
Result<std::shared_ptr<AuthSession>> SigV4AuthManager::CatalogSession(
201246
HttpClient& shared_client,
202247
const std::unordered_map<std::string, std::string>& properties) {
203-
ICEBERG_RETURN_UNEXPECTED(EnsureSdkInitialized());
248+
ICEBERG_RETURN_UNEXPECTED(AwsSdkLifecycle::Instance().EnsureInitialized());
204249
catalog_properties_ = properties;
205250
ICEBERG_ASSIGN_OR_RAISE(auto delegate_session,
206251
delegate_->CatalogSession(shared_client, properties));
@@ -325,34 +370,13 @@ Result<std::unique_ptr<AuthManager>> MakeSigV4AuthManager(
325370
return std::make_unique<SigV4AuthManager>(std::move(delegate));
326371
}
327372

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-
}
373+
Status InitializeAwsSdk() { return AwsSdkLifecycle::Instance().Initialize(); }
339374

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-
}
375+
Status FinalizeAwsSdk() { return AwsSdkLifecycle::Instance().Finalize(); }
352376

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

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

357381
} // namespace iceberg::rest::auth
358382

0 commit comments

Comments
 (0)