This is a request for the typed persistence API to make the PersistentBehavior a bit more composable.
Currently, calling onRecoveryCompleted replaces any existing callback, so something like the following is not possible:
val behavior = PersistentBehaviors.receive { ... }
.onRecoveryCompleted(...)
// Somewhere else, decorate the behavior with another recovery callback
behavior.onRecoveryCompleted(...)
Having onRecoveryCompleted chain existing callbacks would be really nice to support this. I suppose the same applies to onSnapshot.
After pondering this a bit I think that it would be bad to chain in the on methods because there are no obvious semantics around which callback runs first, what happens if one callback fails etc.
Therefore I'm leaning more towards being able to access the previous defined callback if there is one and compose any way you want with an additional function. Something like:
val previous: Option[State => Unit] = persistentBehavior.onRecoveryCompletedCallback
val withComposedCallback = persistentBehavior.onRecoveryCompleted { state =>
// here we can do things in any order we want, catch exceptions etc.
otherCallback(state)
previous.foreach(cb => cb(state))
}
Wdyt about this? Ping @patriknw
Those callbacks have been nagging me for another reason. They are a different kind of API than we have for ordinary actors (we don't use much callbacks). I wonder if we should make them look more like signals, i.e. a signal message you receive.
EventSourcedBehavior[Command, Event, State](
persistenceId = PersistenceId(id),
emptyState = State(Nil),
commandHandler = commandHandler,
eventHandler = eventHandler)
.receiveSignal {
case RecoveryCompleted(state) => ...
case RecoverFailed(ex) =>
case SnapshotCompleted(meta, result) =>
}
Composition would be possible in similar way as Johan suggests, i.e. that the registered signal handler is accessible and can be delegated to with for example .orElse.
That would also make it easier to add more such signals in the future in the javadsl, which is an abstract class where we can't really add more methods.
I think that's a pretty neat idea
Then it could also support ordinary Terminated message this way.
BTW I recently added preRestart and postPost hooks and those should ofc also be like this.
Most helpful comment
Then it could also support ordinary
Terminatedmessage this way.BTW I recently added preRestart and postPost hooks and those should ofc also be like this.