Skip to content

[SPARK-58932][SS][4.1] Close the accepted socket in TransformWithStateInPySparkStateServer - #58309

Closed
j1wonpark wants to merge 1 commit into
apache:branch-4.1from
j1wonpark:SPARK-58932-4.1
Closed

[SPARK-58932][SS][4.1] Close the accepted socket in TransformWithStateInPySparkStateServer#58309
j1wonpark wants to merge 1 commit into
apache:branch-4.1from
j1wonpark:SPARK-58932-4.1

Conversation

@j1wonpark

Copy link
Copy Markdown
Contributor

What changes were proposed in this pull request?

Backport of #58205 to branch-4.1: run the request loop of TransformWithStateInPySparkStateServer.run() inside Utils.tryWithResource so the accepted socket is always closed. This branch does not have SPARK-58977, so unlike master the accept() call is unchanged.

Why are the changes needed?

The accepted socket is never closed, leaking one file descriptor per task until the executor exhausts the ephemeral port range (java.net.BindException). See #58205 for details.

Does this PR introduce any user-facing change?

No.

How was this patch tested?

The two tests added in #58205 are included; TransformWithStateInPySparkStateServerSuite passes locally on this branch.

Was this patch authored or co-authored using generative AI tooling?

Yes. Generated-by: Claude Opus 5

…SparkStateServer

Run the request loop of `TransformWithStateInPySparkStateServer.run()` inside `Utils.tryWithResource` so the socket returned by `stateServerSocket.accept()` is always closed.

`run()` accepts a connection from the Python worker but never closes it. The task completion listener closes only the listening `ServerSocketChannel`, so the accepted connection's file descriptor is held until the executor exits.

`initStateServer()` binds an ephemeral port per task, so a long-running streaming query leaks one socket per task. Once the ephemeral port range is exhausted, every new connection on that executor fails with `java.net.BindException: Cannot assign requested address`, which also takes down unrelated connections such as the Kafka source.

The loop has several early returns, so the close has to be tied to the scope.

No.

Two tests added to `TransformWithStateInPySparkStateServerSuite`, covering the path where the request loop is never entered and the EOF early-return path. Both fail without the fix. The suite previously had no test calling `run()`.

Yes. Generated-by: Claude Opus 5

Closes apache#58205 from j1wonpark/tws-state-server-socket-leak.

Authored-by: Jiwon Park <jpark92@outlook.kr>
Signed-off-by: Jungtaek Lim <kabhwan.opensource@gmail.com>
(cherry picked from commit c5fbdf7)

@uros-b uros-b left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks byte-identical to #58308, right? If this is the case, I think #58308 can be merged to both 4.2 and 4.1

@HeartSaVioR HeartSaVioR left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1

@HeartSaVioR

Copy link
Copy Markdown
Contributor

Merged via #58308

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants