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

He-Pin 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 923c13f6c9 Clarify mutable state updates in typed persistence (#3655)
923c13f6c9 is described below

commit 923c13f6c97b74e1ee350a430478180036b85fa7
Author: He-Pin(kerr) <[email protected]>
AuthorDate: Fri Oct 23 21:50:43 2026 +0800

    Clarify mutable state updates in typed persistence (#3655)
    
    * Clarify mutable state updates in typed persistence
    
    Motivation:
    
    Mutable state guidance needs to distinguish event handlers from command 
handlers and explain that mutating durable state still requires persistence.
    
    Modification:
    
    Document where event-sourced state may be changed, require persist for a 
mutated durable-state instance, and explain durability and asynchronous access 
constraints around callbacks.
    
    Result:
    
    Scala and Java users receive guidance consistent with the current 
persistence lifecycle.
    
    Tests:
    
    - Tests: Not run - docs only.
    - Passed: `docs/paradox`.
    - Passed: `+headerCheckAll`.
    - Full `validatePullRequest` is left to remote CI.
    
    References:
    
    - Refs [akka/akka-core#32108](https://github.com/akka/akka-core/pull/32108).
    - Upstream commit: 
[15be3cfb2b198cb72da907eeb1059ecae09bff7c](https://github.com/akka/akka-core/commit/15be3cfb2b198cb72da907eeb1059ecae09bff7c).
    - Source snapshot: Akka `v2.9.0` 
(`bf20e967571574994ccb3cae411401f5a9021ab9`). Its 
[license](https://github.com/akka/akka-core/blob/v2.9.0/LICENSE) names 
2026-10-23 as the Change Date and Apache License 2.0 as the Change License. 
`LICENSE` and `NOTICE` record the source, and original copyright notices are 
retained. Headers were generated/checked with the project sbt tasks.
    
    * Keep licensing metadata outside the migration change
    
    Motivation:
    Keep PR #3655 scoped to its code or documentation change.
    
    Modification:
    Restore the root LICENSE and NOTICE files to main.
    
    Result:
    The migration diff retains its source headers without repository-level 
licensing edits.
    
    Tests:
    - git diff --check passed.
    - Verified every other file is unchanged; prior focused validation still 
applies.
    
    References:
    Refs #3655.
    
    * Clarify durable state updates to preserve empty state
    
    Motivation:
    Mutating the initial durable state also mutates the empty state reused by
    deletion and recovery.
    
    Modification:
    Recommend fresh updated state instances and preserving the initial empty
    state, while retaining persistence-success and thread-safety guidance.
    
    Result:
    The documentation describes safe state updates supported by the current
    implementation.
    
    Tests:
    - Not run - docs only
    - sbt -batch -Dsbt.supershell=false docs/paradox: passed
    - git diff --check: passed
    - Qoder stdout follow-up: No must-fix findings
    
    References:
    Refs #3655
    
    * Clarify the durable-state mutation rule #3655
    
    Motivation:
    The review asked for direct guidance when using a mutable durable-state 
class.
    
    Modification:
    State that callers must not mutate the current instance in place and must 
pass a new instance to persist.
    
    Result:
    The update rule is explicit alongside the empty-state and 
persistence-success guidance.
    
    Tests:
    Validation used a local integration checkout with current main and the 
other review fixes.
    
    - Runtime tests: Not run - docs only.
    - docs/paradox, headerCreateAll, and +headerCheckAll: passed.
    - git diff --check: passed.
    - Full validation is delegated to remote CI.
    
    References:
    Refs #3655.
---
 docs/src/main/paradox/typed/durable-state/persistence.md | 7 +++++++
 docs/src/main/paradox/typed/persistence.md               | 3 ++-
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/docs/src/main/paradox/typed/durable-state/persistence.md 
b/docs/src/main/paradox/typed/durable-state/persistence.md
index d882d716d1..7d139cea7c 100644
--- a/docs/src/main/paradox/typed/durable-state/persistence.md
+++ b/docs/src/main/paradox/typed/durable-state/persistence.md
@@ -96,6 +96,13 @@ The two most commonly used effects are:
 * `persist` will persist the latest value of the state. No history of state 
changes will be stored
 * `none` no state to be persisted, for example a read-only command
 
+The state is typically an immutable class, with a new instance passed to the 
`persist` effect.
+If using a mutable state class, do not mutate the current state instance in 
place; pass a new instance to `persist`.
+Keep the initial `emptyState` instance unchanged, since it is reused after 
deletion and when recovery
+finds no stored state. The change is only durable after persistence completes 
successfully; use
+`thenRun` for side effects that depend on that success. Do not mutate the 
state from asynchronous
+callbacks or other threads, which may race with serialization or subsequent 
commands.
+
 More effects are explained in @ref:[Effects and Side 
Effects](#effects-and-side-effects).
 
 In addition to returning the primary `Effect` for the command, 
`DurableStateBehavior`s can also 
diff --git a/docs/src/main/paradox/typed/persistence.md 
b/docs/src/main/paradox/typed/persistence.md
index a6ab6a046c..ead09afc2c 100644
--- a/docs/src/main/paradox/typed/persistence.md
+++ b/docs/src/main/paradox/typed/persistence.md
@@ -147,7 +147,8 @@ In the case of multiple persisted events, the 
`eventHandler` is called with each
 
 The state is typically defined as an immutable class and then the event 
handler returns a new instance of the state.
 You may choose to use a mutable class for the state, and then the event 
handler may update the state instance and
-return the same instance. Both immutable and mutable state is supported.
+return the same instance. Both immutable and mutable state is supported, but 
mutable state must only be modified
+in the event handler, never in the command handler.
 
 The same event handler is also used when the entity is started up to recover 
its state from the stored events.
 


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

Reply via email to