This is an automated email from the ASF dual-hosted git repository.

hepin pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/pekko.git


The following commit(s) were added to refs/heads/main by this push:
     new 491c9550f7 Handle unexpected stop of TLS actor gracefully (#2801)
491c9550f7 is described below

commit 491c9550f794e0232da989cbed824c312b0caeb4
Author: He-Pin(kerr) <[email protected]>
AuthorDate: Sat Mar 28 17:01:02 2026 +0800

    Handle unexpected stop of TLS actor gracefully (#2801)
    
    When a TLS actor terminates unexpectedly (without going through the
    normal fail/pumpFinished paths), propagate errors to both transport
    and user outputs with a descriptive message including the peer host
    and port. This resolves the long-standing FIXME about unexpected
    actor death.
    
    A 'stopped' flag tracks whether the actor has already completed its
    cleanup through the normal paths, so postStop only signals errors for
    truly unexpected terminations.
    
    Upstream: akka/akka-core@b4b2fcbaaa
    Cherry-picked from akka/akka-core v2.8.0, which is now Apache licensed.
---
 .../scala/org/apache/pekko/stream/impl/io/TLSActor.scala | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git 
a/stream/src/main/scala/org/apache/pekko/stream/impl/io/TLSActor.scala 
b/stream/src/main/scala/org/apache/pekko/stream/impl/io/TLSActor.scala
index 8bceeb2f33..02cdeda571 100644
--- a/stream/src/main/scala/org/apache/pekko/stream/impl/io/TLSActor.scala
+++ b/stream/src/main/scala/org/apache/pekko/stream/impl/io/TLSActor.scala
@@ -70,6 +70,8 @@ import pekko.util.ByteString
 
   import TLSActor._
 
+  private var stopped = false
+
   private val maxTLSIterations = 1000
   private var unwrapPutBackCounter: Int = 0
   protected val outputBunch = new OutputBunch(outputCount = 2, self, this)
@@ -500,12 +502,21 @@ import pekko.util.ByteString
       outputBunch.error(TransportOut, e)
     }
     outputBunch.error(UserOut, e)
+    stopped = true
     pump()
   }
 
-  // FIXME: what happens if this actor dies unexpectedly?
   override def postStop(): Unit = {
-    if (tracing) log.debug("postStop")
+    if (!stopped) {
+      val e = new RuntimeException(
+        s"Unexpected termination of TLS actor for connection to 
${engine.getPeerHost}:${engine.getPeerPort}")
+      log.warning(e.getMessage)
+      inputBunch.cancel()
+      outputBunch.error(TransportOut, e)
+      outputBunch.error(UserOut, e)
+    } else if (tracing) {
+      log.debug("postStop")
+    }
     super.postStop()
   }
 
@@ -515,6 +526,7 @@ import pekko.util.ByteString
     inputBunch.cancel()
     outputBunch.complete()
     if (tracing) log.debug(s"STOP Outbound Closed: ${engine.isOutboundDone} 
Inbound closed: ${engine.isInboundDone}")
+    stopped = true
     context.stop(self)
   }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to