SiriusTL666 opened a new pull request, #13009:
URL: https://github.com/apache/seatunnel/pull/13009

   ### Purpose of this pull request
   
   The FTP file system creates its client and calls `connect(host, port)` 
without ever setting a read timeout.
   
   `FTPClient` inherits `_timeout_` from `SocketClient`, and that field 
defaults to `0`, which means **wait indefinitely**. So a server that accepts 
the TCP connection but never sends a reply leaves the calling thread parked in 
a read with no deadline. That covers a stalled server, a firewall or load 
balancer that accepts the connection and silently drops the traffic, and a 
server that stops answering halfway through a listing. Nothing surfaces at the 
job level: the thread is blocked, so there is no error to retry and no progress 
to report.
   
   The connect step itself is not the problem. `SocketClient` already defaults 
`connectTimeout` to 60000 ms, so an unreachable host fails on its own. The 
unbounded wait is specifically the control-channel read: the greeting, the 
login exchange, and every listing or command reply.
   
   ### Does this PR introduce _any_ user-facing change?
   
   Yes. A new `control_timeout` option (milliseconds, default `60000`) bounds 
each control-connection reply.
   
   - Declared on **both** source and sink, because reads and writes share the 
same control channel. Declaring it on only one side would leave the other with 
the unbounded wait.
   - Applied **before** `connect()`, so the greeting is covered. Applying it 
after would leave exactly the first read unprotected, which is the read that 
hangs most often.
   - `control_timeout = 0` restores the previous wait-indefinitely behaviour.
   - Recorded in the `dev` section of `incompatible-changes.md` (EN and ZH), 
because a job that previously hung silently in `RUNNING` now fails with a 
timeout.
   
   ### Does this PR introduce _any_ user-facing change? (second part)
   
   Two handshake failures left the client socket open: a rejected greeting 
(`!FTPReply.isPositiveCompletion`) and a refused login both threw without 
disconnecting. The TCP connection is already established at those points, so 
the connection stayed pinned on the server until the server gave up on it. Both 
paths now disconnect before throwing. The reply code for the login failure is 
captured before `disconnect()` so the error message still reports the server's 
code.
   
   ### How was this patch tested?
   
   Local, JDK 17, `connector-file-ftp` module: **26/26 pass** 
(`FtpFileFactoryTest` 4, `SeaTunnelFTPFileSystemTest` 13, new 
`SeaTunnelFTPFileSystemTimeoutTest` 9). `spotless:check` passes.
   
   The timeout cannot be observed through a getter, so the new tests intercept 
construction with Mockito and assert:
   
   - the exact value passed to `setDefaultTimeout` for the default and for a 
configured value;
   - that it is called **before** `connect`, via `InOrder`, which is what 
decides whether the greeting is protected;
   - that `0` is passed through unchanged as the opt-out;
   - that both the rejected-greeting and refused-login paths call `disconnect`;
   - that a successful call still disconnects exactly once, so the new 
failure-path disconnect does not double-release;
   - that the option is declared in both factories, and that the value reaches 
the Hadoop configuration map.
   
   Both fixes were reverse-verified. Reverting `setDefaultTimeout` turns 4 
tests red (`Wanted but not invoked`); reverting the two `disconnect` calls 
turns 2 tests red.
   
   Behaviour was also confirmed against a real `FTPClient` before writing the 
fix: with a server that sends a `220` greeting and then goes silent, `login()` 
was still blocked after 6 s with no timeout set, and threw 
`SocketTimeoutException` at 2.0 s with `setDefaultTimeout(2000)`. The same 
check showed `connectTimeout` already defaulting to 60000, which is why this 
change only targets the control-channel read.
   
   ### Check list
   
   - [x] I have read the [Contributing 
Guide](https://seatunnel.apache.org/community/contribute)
   - [x] New feature and improvements added
   - [ ] Bug fixes (mark `x`) if this PR fixes a bug
   - [x] Docs updated (connector tables EN/ZH, `incompatible-changes.md` EN/ZH)
   


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