uros-b commented on code in PR #57778:
URL: https://github.com/apache/spark/pull/57778#discussion_r3719254931


##########
python/pyspark/sql/connect/client/reattach.py:
##########
@@ -109,7 +109,9 @@ def __init__(
         # Initial iterator comes from ExecutePlan request.
         # Note: This is not retried, because no error would ever be thrown 
here, and GRPC will only
         # throw error on first self._has_next().
-        self._metadata = metadata
+        # Convert metadata to a list to ensure it remains re-iterable across 
all RPCs
+        # (ReattachExecute, ReleaseExecute), so auth headers are always 
present.
+        self._metadata = list(metadata)

Review Comment:
   +1 with @HyukjinKwon's concern. The PR introduces an internal inconsistency: 
self._metadata = list(metadata) (line 114) consumes the original metadata 
iterable, but the ExecutePlan call immediately below (line 120) still passes 
metadata=metadata; the now-potentially-exhausted original, rather than 
metadata=self._metadata. For the real-world caller (ChannelBuilder.metadata() 
returns a list), this is currently harmless, but the type annotation accepts 
any Iterable[Tuple[str, str]], which includes one-shot generators. The partial 
fix leaves the initial ExecutePlan call unchanged and creates a silent 
correctness trap: if a custom ChannelBuilder passes a generator, the initial 
RPC consumes it and the materialized self._metadata is empty, corrupting all 
subsequent RPCs while appearing to be protected.



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