He-Pin commented on code in PR #3096:
URL: https://github.com/apache/pekko/pull/3096#discussion_r3444075901
##########
actor/src/main/scala/org/apache/pekko/actor/FSM.scala:
##########
@@ -779,11 +779,25 @@ trait FSM[S, D] extends Actor with Listeners with
ActorLogging {
* transition handling
*/
private var transitionEvent: List[TransitionHandler] = Nil
+ private val watchedListeners: mutable.Set[ActorRef] = mutable.Set.empty
private def handleTransition(prev: S, next: S): Unit = {
Review Comment:
🟡 **Suggestion: listener leak when FSM already watches the listener actor**
When `isWatching(actorRef)` returns `true` (the FSM's business logic already
called `context.watch()` on this actor), `watchWith` is skipped and the actor
is not added to `watchedListeners`. If that actor later terminates, the FSM
receives a plain `Terminated` instead of `ListenerTerminated`, and the listener
is never removed from `listeners`.
Adding a `case Terminated(actorRef) => listeners.remove(actorRef)` handler
to the `receive` block would be a **breaking change** (it would intercept
`Terminated` before it reaches user state functions via `processMsg`). So this
edge case may be acceptable as-is.
Consider adding a log warning when `isWatching` is true at subscription
time, so users know the listener won't be auto-cleaned:
```scala
private def addListener(actorRef: ActorRef): Unit = {
if (listeners.add(actorRef)) {
if (!context.asInstanceOf[ActorCell].isWatching(actorRef)) {
context.watchWith(actorRef, ListenerTerminated(actorRef))
watchedListeners += actorRef
} else {
log.warning(
"Listener [{}] is already watched by this FSM; it will not be " +
"automatically removed on termination. Use
UnsubscribeTransitionCallBack explicitly.",
actorRef)
}
}
}
```
Not blocking — the common case is handled correctly.
--
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]