This is an automated email from the ASF dual-hosted git repository.
laskoviymishka pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/iceberg-go.git
The following commit(s) were added to refs/heads/main by this push:
new 8eb69ef0d docs(table): PlanIO Close does not wait for active ReadTasks
iterators (#2192)
8eb69ef0d is described below
commit 8eb69ef0d175b10d1f2434535a9f30eb76b2abdd
Author: Revanth <[email protected]>
AuthorDate: Wed Oct 14 11:34:56 2026 -0500
docs(table): PlanIO Close does not wait for active ReadTasks iterators
(#2192)
---
table/scan_planning.go | 5 +++--
table/scan_planning_test.go | 11 ++++++-----
2 files changed, 9 insertions(+), 7 deletions(-)
diff --git a/table/scan_planning.go b/table/scan_planning.go
index 4b6a12162..ddf31dfb2 100644
--- a/table/scan_planning.go
+++ b/table/scan_planning.go
@@ -128,8 +128,9 @@ type ScanPlanningRequest struct {
// table's FileIO. Replacing the plan releases that Scan's ownership; the old
IO
// closes after its remaining scan owners and active record iterators finish.
// Call Scan.Close when the scan is no longer needed, including when planning
-// succeeds but its tasks are not read. Close is idempotent and waits for
active
-// ReadTasks iterators before the plan IO is closed.
+// succeeds but its tasks are not read. Close is idempotent and does not wait:
+// active ReadTasks iterators keep the plan IO open, and it closes once the
last
+// of them finishes.
// This ties a plan-scoped scan to PlanFiles -> ReadTasks: tasks from a remote
// plan must be read by the Scan that produced them or one of its derived
scans.
// A Scan carrying plan-scoped IO is not safe for concurrent PlanFiles or
diff --git a/table/scan_planning_test.go b/table/scan_planning_test.go
index 1363abdb0..c0a7cbc9e 100644
--- a/table/scan_planning_test.go
+++ b/table/scan_planning_test.go
@@ -315,7 +315,10 @@ func TestScanCloseReleasesPlanIO(t *testing.T) {
require.ErrorIs(t, err, ErrInvalidOperation)
}
-func TestScanCloseWaitsForActiveReadTasks(t *testing.T) {
+// TestScanCloseKeepsPlanIOOpenForActiveReadTasks checks that Close returns
+// without waiting for an active ReadTasks iterator, and that the iterator
keeps
+// the plan IO open until it finishes.
+func TestScanCloseKeepsPlanIOOpenForActiveReadTasks(t *testing.T) {
t.Parallel()
pio := &countingPlanIO{fs: icebergio.LocalFS{}}
@@ -326,14 +329,12 @@ func TestScanCloseWaitsForActiveReadTasks(t *testing.T) {
_, records, err := scan.ReadTasks(context.Background(), nil)
require.NoError(t, err)
- closeDone := make(chan error, 1)
- go func() { closeDone <- scan.Close() }()
- assert.Equal(t, 0, pio.closeCalls)
+ require.NoError(t, scan.Close())
+ assert.Equal(t, 0, pio.closeCalls, "the active iterator still holds the
plan IO")
for _, err := range records {
require.NoError(t, err)
}
- require.NoError(t, <-closeDone)
assert.Equal(t, 1, pio.closeCalls)
}