Skip to content

Commit c570375

Browse files
authored
fix: re-read sessionCache inside synchronized block in getOrCreateSessionCache (#242)
The double-checked locking pattern in getOrCreateSessionCache() had a bug: the local variable 'cache' was not updated after another thread won the initialization race inside the synchronized block. The losing thread would return null, causing a NullPointerException at cache.cachedSession() in tableSession() (line 94). This surfaces when multiple threads call tableSession() simultaneously on the first Iceberg commit — for example, when an Iceberg Kafka Connect sink flushes several Parquet files in parallel. It became observable in iceberg-kafka-connect 1.11.0 after apache/iceberg#13215 changed S3V4RestSignerClient to call authManager().tableSession() on every S3 request instead of caching the session per instance. Fix: re-read sessionCache from the volatile field inside the synchronized block so the losing thread picks up the value set by the winner.
1 parent 2d797e8 commit c570375

1 file changed

Lines changed: 2 additions & 1 deletion

File tree

oauth2/core/src/main/java/com/dremio/iceberg/authmgr/oauth2/OAuth2Manager.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,8 @@ private AuthSessionCache getOrCreateSessionCache(Map<String, String> properties)
136136
AuthSessionCache cache = sessionCache;
137137
if (cache == null) {
138138
synchronized (this) {
139-
if (sessionCache == null) {
139+
cache = sessionCache;
140+
if (cache == null) {
140141
OAuth2Config config = OAuth2Config.from(properties);
141142
cache = new AuthSessionCache(name, config.getSystemConfig().getSessionCacheTimeout());
142143
sessionCache = cache;

0 commit comments

Comments
 (0)