prashantwason opened a new pull request, #19790:
URL: https://github.com/apache/hudi/pull/19790

   **Describe the issue this Pull Request addresses**
   
   DistributedRegistry is a JVM-wide singleton (cached in 
Registry.REGISTRY_MAP) and a Spark AccumulatorV2. When executor metrics are 
enabled (hoodie.metrics.executor.enable=true) and multiple Hudi write clients 
are created within the same JVM (e.g. batch frameworks processing multiple 
tables sequentially), the cached DistributedRegistry instance retains metadata 
set from a prior SparkContext registration.
   
   On a subsequent initRegistry() call:
   - AccumulatorV2.isRegistered() returns false — the id is no longer in the 
current AccumulatorContext
   - The guard in DistributedRegistry.register() lets the call through
   - AccumulatorV2.register() throws IllegalStateException("Cannot register an 
Accumulator twice") because metadata is non-null
   
   This crashes the write with HoodieException: Failed to instantiate Metadata 
table.
   
   **Summary and Changelog**
   
   Fix DistributedRegistry.register() to handle the stale-singleton case where 
the accumulator was registered to a previous SparkContext that no longer exists.
   
   - DistributedRegistry.register(): on IllegalStateException, create a fresh 
AccumulatorV2, copy counters from the stale instance, register the fresh 
instance, and swap it into Registry.REGISTRY_MAP. Changed return type from void 
to DistributedRegistry so callers receive the potentially-replaced instance.
   - SparkHoodieBackedTableMetadataWriter.initRegistry(): use the returned 
registry from register().
   - SparkHoodieBackedTableMetadataWriterTableVersionSix.initRegistry(): same.
   - HoodieSparkEngineContext.getMetricRegistry(): same.
   - TestDistributedRegistry: added testRegisterIdempotent and 
testRegisterHandlesStaleAccumulator.
   
   **Impact**
   
   No public API or user-facing feature change. No performance impact — the fix 
only alters behavior in the error path (stale accumulator from a dead 
SparkContext). The normal registration path is unchanged.
   
   **Risk Level**
   
   Low. The catch block only fires when AccumulatorV2.register() throws 
IllegalStateException, which is the exact crash this fixes. The fresh instance 
is functionally identical to the original, with counters preserved.
   
   **Documentation Update**
   
   None. No new configs or user-facing changes.
   
   **Contributor's checklist**
   
   - [x] Read through contributor's guide
   - [x] Enough context is provided in the sections above
   - [x] Adequate tests were added if applicable
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to