dlscjf151 opened a new issue, #20170:
URL: https://github.com/apache/pinot/issues/20170

   ## Problem
   
   `TimeBoundaryStrategyService` caches one `TimeBoundaryStrategy` instance per 
strategy name and returns it to every caller. For hybrid logical tables, 
`LogicalTableRouteProvider` initializes that shared instance with 
request-specific logical-table metadata and later computes its time boundary.
   
   `MinTimeBoundaryStrategy.init()` replaces `_dateTimeFormatSpecMap` with an 
empty `HashMap` before populating it. Another request can observe the 
empty/partially initialized map, or use the metadata initialized for a 
different logical table.
   
   When the computed boundary is null, 
`LogicalTableRouteProvider.fillRouteMetadata()` drops the OFFLINE tables. A 
request can therefore silently omit OFFLINE data rather than return an explicit 
query error. Different logical tables can also use each other's time boundary.
   
   This affects single-stage hybrid logical-table routing, including 
federation; it is not restricted to federation deployments.
   
   ## Deterministic reproduction
   
   1. Look up the `min` strategy for request A and initialize it with 
`includedTables=[table1_OFFLINE]`.
   2. Look up the `min` strategy for request B and initialize it with 
`includedTables=[table2_OFFLINE]`.
   3. Compute A's boundary after B's initialization.
   4. A returns table2's boundary instead of table1's boundary, because both 
lookups returned the same mutable instance.
   
   A focused regression reproduces this interleaving without sleeps or 
probabilistic scheduling. A separate local smoke also reproduces it through the 
real `LogicalTableRouteProvider.fillTableConfigMetadata()` / 
`fillRouteMetadata()` path.
   
   ## Expected behavior
   
   Each logical-table request computes its boundary from its own configuration 
and preserves the correct OFFLINE routes, independently of other requests.
   
   ## Proposed fix
   
   Cache `ServiceLoader.Provider<TimeBoundaryStrategy>` objects instead of 
strategy instances. Call `Provider.get()` on each lookup to create a fresh 
strategy instance. The service registry remains a singleton; only the stateful 
strategy is request-scoped. This uses the JDK service-provider mechanism 
without adding a dependency, a global lock, or a new strategy SPI method.
   
   ## Source baseline
   
   Apache Pinot master commit `0a53497fddfc61220feabc5b8f62516f4183525f`.
   
   ## Tooling disclosure
   
   This issue text was prepared using OpenAI coding-assistant assistance.
   


-- 
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]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to