He-Pin opened a new issue, #3232:
URL: https://github.com/apache/pekko/issues/3232

   ### Motivation
   When an EventSourcedBehavior actor is stopped during the snapshot loading 
phase of recovery, the user-registered `PostStop` signal handler is never 
invoked. This is inconsistent with every other recovery phase 
(`RequestingRecoveryPermit`, `ReplayingEvents`, `Running`), all of which 
forward `PostStop` to the user's signal handler. Users relying on `PostStop` 
for cleanup (releasing resources, notifying other actors, etc.) will see their 
handler silently skipped if the actor stops during snapshot loading.
   
   ### Current behavior
   In `ReplayingSnapshot.scala`, the signal handler is composed using `.orElse`:
   
   ```scala
   .receiveSignal(returnPermitOnStop.orElse {
     case (_, PoisonPill) =>
       stay(receivedPoisonPill = true)
     case (_, signal) =>
       if (setup.onSignal(setup.emptyState, signal, catchAndLog = true)) 
Behaviors.same
       else Behaviors.unhandled
   })
   ```
   
   `returnPermitOnStop` (defined in `ExternalInteractions.scala`) matches 
`PostStop` and `PreRestart` first:
   
   ```scala
   protected def returnPermitOnStop = {
     case (_, PostStop) =>
       tryReturnRecoveryPermit("PostStop")
       Behaviors.stopped
     case (_, PreRestart) =>
       tryReturnRecoveryPermit("PreRestart")
       Behaviors.stopped
   }
   ```
   
   Since `returnPermitOnStop` is tried first via `.orElse`, it intercepts 
`PostStop` (and `PreRestart`) and returns `Behaviors.stopped` without ever 
calling `setup.onSignal`. The user's signal handler is never reached.
   
   ### Expected behavior
   `PostStop` and `PreRestart` signals should be forwarded to the user's signal 
handler via `setup.onSignal` during the snapshot loading phase, consistent with 
all other recovery phases. The recovery permit should still be returned, but 
only after the user handler has been invoked.
   
   ### Code evidence
   - 
`persistence-typed/src/main/scala/org/apache/pekko/persistence/typed/internal/ReplayingSnapshot.scala`
 (line 88): `returnPermitOnStop.orElse` intercepts `PostStop` before the user 
handler.
   - 
`persistence-typed/src/main/scala/org/apache/pekko/persistence/typed/internal/ExternalInteractions.scala`
 (lines 148-156): `returnPermitOnStop` definition that catches 
`PostStop`/`PreRestart` without calling `setup.onSignal`.
   - 
`persistence-typed/src/main/scala/org/apache/pekko/persistence/typed/internal/RequestingRecoveryPermit.scala`
 (lines 70-76): Does NOT use `returnPermitOnStop`; forwards `PostStop` to 
`setup.onSignal` correctly.
   - 
`persistence-typed/src/main/scala/org/apache/pekko/persistence/typed/internal/ReplayingEvents.scala`
 (lines 122-129): Does NOT use `returnPermitOnStop`; forwards `PostStop` to 
`setup.onSignal` correctly.
   
   ### Reproduction
   1. Create an `EventSourcedBehavior` with a `receiveSignal` handler that 
handles `PostStop`.
   2. Ensure the actor has a snapshot available in the snapshot store.
   3. Stop the actor while it is in the snapshot loading phase (e.g., by 
sending `PoisonPill` immediately after spawn, or by having the snapshot store 
respond slowly while the actor is stopped).
   4. Observe that the `PostStop` handler is never invoked.
   
   Suggested test: Add a test in the persistence-typed test suite that spawns 
an `EventSourcedBehavior` with a `PostStop` signal handler, uses a 
slow/controllable snapshot store, and verifies the signal handler is called 
when the actor is stopped during snapshot loading.
   
   ### Impact
   - Module: `pekko-persistence-typed`
   - Affects any `EventSourcedBehavior` that registers a `PostStop` or 
`PreRestart` signal handler and may be stopped during the snapshot loading 
phase.
   - The `PreRestart` signal is also affected by the same issue (intercepted 
without user handler invocation).


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