Apache Polaris is an open source, REST-compatible catalog for Apache Iceberg — designed to work across engines including Apache Spark, Apache Flink, Trino, and others through a unified catalog API.
7 pull requests merged across thread safety, core correctness, and codebase hygiene.
Thread Safety — InMemoryBufferEventListener
Three contributions addressing concurrency correctness in the in-memory event buffer, surfaced and fixed in sequence.
Give the in-memory event buffer its own lock
PR #4577 — Merged June 2026
Follow-up to PR #4498. The prior fix synchronized onComplete() against UnicastProcessor’s intrinsic lock — which worked only because Mutiny’s UnicastProcessor.onNext() happened to be synchronized. As @adutra noted, this leaned on a Mutiny implementation detail that could silently break in a future version.
This PR gives InMemoryBufferEventListener its own dedicated lock: an EventProcessor wrapper that holds a ReentrantLock and routes both onNext and onComplete through it. No longer dependent on how Mutiny locks internally. Also adds a reset() method so tests can reuse the bean after shutdown().
Synchronize onComplete calls in InMemoryBufferEventListener
PR #4498 — Merged May 2026
UnicastProcessor.onNext() is declared public synchronized void in smallrye-mutiny, but onComplete() is not synchronized. A concurrent processEvent (onNext) and eviction-driven onComplete on the same processor had no mutual exclusion — silently dropping events at the eviction boundary.
Wraps both onComplete() call sites (Caffeine eviction listener and shutdown() loop) in synchronized (processor) blocks, acquiring the same intrinsic monitor that onNext() uses.
Synchronize processEvent to satisfy Reactive Streams rule 1.3
PR #4487 — Merged May 2026
Fixes the concurrent onNext() race in InMemoryBufferEventListener.processEvent originally tracked in issue #2568. Reactive Streams rule 1.3 requires onNext to be called sequentially; Mutiny’s UnicastProcessor relies on that contract and concurrent emissions can silently drop events.
Synchronizes on the processor in processEvent so concurrent calls for the same realm serialize. Adds InMemoryBufferEventListenerThreadSafetyTest — 10 threads × 100 events against the same realm via a CountDownLatch barrier, asserting all 1000 events land in the events table.
Core Correctness
Validate default-base-location against storage config on catalog update
PR #4422 — Merged July 2026
Adds validation to reject catalog updates where the new default-base-location falls outside the catalog’s configured allowedLocations. Previously, updating the base location without updating the storage config was silently accepted — but subsequent namespace and table creation would fail because the new location wasn’t in the allowed paths.
Adds validateBaseLocationAgainstStorageConfig() in PolarisAdminService.updateCatalog() — clear error at update time rather than a silent failure downstream.
Extract shared credential rotation pre-condition check
PR #4420 — Merged June 2026
Extracts the duplicated PRINCIPAL_CREDENTIAL_ROTATION_REQUIRED_STATE pre-condition check from PolarisAuthorizerImpl and RangerPolarisAuthorizer into a shared AuthorizationPreConditions utility class. Both authorizers had identical logic to block non-ROTATE_CREDENTIALS operations when a principal is flagged for mandatory credential rotation.
Documentation and Codebase Hygiene
Fix various typos across docs, code, and tooling
PR #4520 — Merged May 2026
7 typo fixes across docs, Java source, shell scripts, and Helm chart tests — including a duplicate-word in a Micrometer metric description visible in ops dashboards.
Remove duplicate ‘for’ in markdown_testing.py
PR #4514 — Merged May 2026
Removes duplicate “for” from a CI tooling print statement in the site integration test runner.