Akka: Typed persistence: register multiple onRecoveryCompleted callbacks

Created on 2 Aug 2018  路  4Comments  路  Source: akka/akka

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.

3 - in progress help wanted persistence typed

Most helpful comment

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.

All 4 comments

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.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

chbatey picture chbatey  路  3Comments

patriknw picture patriknw  路  3Comments

hepin1989 picture hepin1989  路  4Comments

raboof picture raboof  路  3Comments

johanandren picture johanandren  路  3Comments