He-Pin opened a new pull request, #3156:
URL: https://github.com/apache/pekko/pull/3156

   ### Motivation
   
   `TcpOutgoingConnection` retries a failed `finishConnect` by scheduling a 
callback via `context.system.scheduler.scheduleOnce` that calls 
`channelRegistry.register(channel, SelectionKey.OP_CONNECT)` **outside the 
actor's message loop**. If that callback throws (e.g. 
`IllegalArgumentException`, `CancelledKeyException` racing with `postStop`, or 
any `RuntimeException`), the exception is caught by the scheduler/dispatcher 
error handler and **never re-enters the actor's supervision**. As a result, 
`Tcp.CommandFailed` is never delivered and the commander can stay stuck in the 
`connecting` state indefinitely.
   
   See the original field report and analysis in 
[akkadotnet/akka.net#8195](https://github.com/akkadotnet/akka.net/issues/8195) 
— the Pekko code has the same structural issue.
   
   ### Modification
   
   1. Mix in the `Timers` trait on `TcpOutgoingConnection`.
   2. Replace `context.system.scheduler.scheduleOnce(1.millisecond) { 
channelRegistry.register(...) }` with 
`timers.startSingleTimer(RetryFinishConnect, RetryFinishConnect, 
1.millisecond)`, which sends a private self-message processed inside the 
actor's message loop.
   3. Handle `RetryFinishConnect` in the `connecting` state, wrapped in 
`reportConnectFailure` so any exception surfaces as `CommandFailed` to the 
commander.
   
   Benefits over the previous approach:
   - **Exceptions are caught**: `reportConnectFailure` wraps the 
`channelRegistry.register` call, ensuring any `NonFatal` exception is converted 
to `CommandFailed`.
   - **Lifecycle-safe**: `Timers` automatically cancels pending timers when the 
actor stops, removing the latent window where a stale callback could register 
against a channel being torn down.
   - **Consistent with actor model**: the retry runs as a self-message inside 
the actor's message loop, not as an external callback.
   
   ### Result
   
   Exceptions thrown during the `finishConnect` retry path now correctly 
surface as `Tcp.CommandFailed` to the commander, preventing indefinite hangs in 
the `connecting` state.
   
   ### Tests
   
   - `sbt 'actor-tests / Test / testOnly 
org.apache.pekko.io.TcpConnectionSpec'` → 35/35 passed (including new test 
`report failed connection when finishConnect retries are exhausted`)
   
   ### References
   
   Fixes #3135


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