aglinxinyuan opened a new issue, #6881:
URL: https://github.com/apache/texera/issues/6881

   ### What happened?
   
   Amber CI logs (and any deployment reading results from S3-backed Iceberg 
storage) fill with finalizer warnings like:
   
   ```
   [WARN] [org.apache.iceberg.aws.s3.S3InputStream] [Finalizer] - Unclosed 
input stream created by:
        org.apache.iceberg.aws.s3.S3InputStream.<init>(S3InputStream.java:102)
        ...
        
org.apache.texera.amber.util.IcebergUtil$.readDataFileAsIterator(IcebergUtil.scala:464)
        
org.apache.texera.amber.core.storage.result.iceberg.IcebergDocument$$anon$1.hasNext(IcebergDocument.scala:295)
        ...
        
org.apache.texera.amber.core.storage.model.VirtualDocumentSpec.$anonfun$$init$$6(VirtualDocumentSpec.scala:105)
   ```
   
   plus the sibling `Unclosed S3FileIO instance created by:` warnings after 
`IcebergRestCatalogIntegrationSpec`.
   
   These are real resource leaks, not just noise: each one is a Parquet reader 
+ S3 input stream + AWS HTTP-pool slot held until GC finalization.
   
   **Root cause (reader streams):** 
`IcebergDocument.getUsingFileSequenceOrder`'s iterator opened the Parquet 
reader inside `hasNext`. The existing closes cover file-advance, exhaustion, 
and (lazily) the `until` limit — but two consumer shapes never hit any of them:
   
   | Consumer shape | Why it leaks |
   |---|---|
   | Probes — `isEmpty` / `nonEmpty` / lone `hasNext` | `hasNext` opens a 
stream to answer, caller abandons the iterator; no close point ever runs |
   | Bounded reads — `getRange(from, until)` consumed to exactly the limit | 
The limit close lives in a *subsequent* `hasNext` call that bounded consumers 
never make |
   
   **Root cause (S3FileIO):** `IcebergRestCatalogIntegrationSpec` never closes 
its `RESTCatalog`; Iceberg 1.9.2 tracks per-table `FileIO` instances 
(`FileIOTracker`) and closes them with the catalog, so the missing close leaks 
one `S3FileIO` per `createTable`/`loadTable`.
   
   **Fix:** make `hasNext` resource-free — it claims the next data file from 
`FileScanTask.recordCount` metadata alone (the same field the existing 
whole-file skip already trusts; `planFiles()` never splits files in Iceberg 
1.9.2 and amber's write path is strictly append-only, so the count is exact). 
The Parquet reader opens lazily in `next()`, which also closes it 
deterministically the moment a bounded read has served its last record. Plus 
`afterAll` catalog close in the REST catalog spec.
   
   **Known residual leak paths (pre-existing, not regressed — follow-up 
candidates):**
   
   | Call site | Shape |
   |---|---|
   | `SyncExecutionResource.collectOperatorResult` visualization branch | 
unbounded `get()` + `next()` + early return — leaks deterministically on every 
sync fetch of a visualization result; a bounded `getRange(0, totalCount)` would 
now close deterministically |
   | `SyncExecutionResource` oversized-first-tuple return / swallowed-exception 
catch | abandons mid-file |
   | `ResultExportService` CSV/Arrow streaming | leaks only if the HTTP client 
disconnects mid-download |
   | `InputPortMaterializationReaderThread` | leaks only on exception/interrupt 
mid-replay |
   
   ### How to reproduce?
   
   1. Run the amber storage/integration specs against S3-backed Iceberg storage 
(e.g. `IcebergDocumentSpec`, which inherits `VirtualDocumentSpec` — its "clear 
the document" test does `document.get().nonEmpty`), or call 
`document.get().nonEmpty` / `getRange(a, b).toList` against any populated 
S3-backed `IcebergDocument`.
   2. Wait for a GC cycle (CI runs trigger plenty).
   3. Observe `[S3InputStream] Unclosed input stream created by …` finalizer 
warnings pointing at `IcebergUtil.readDataFileAsIterator` via 
`IcebergDocument$$anon$1.hasNext`.
   
   ### Version/Branch
   
   `main` (429be110a7), Iceberg 1.9.2.
   
   ### Relevant log output
   
   See the stack traces under "What happened?" — observed in the 
`amber-integration` and `amber` CI jobs (e.g. runs on PR #6797).
   


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