Reputation: 613
We use EventSourcedBehavior from akka-persistence 2.6.15 for an CQRS/EventSourcing application, with akka-persistence-jdbc 4.0.0 for storing events and snapshots in PostgreSQL DB.
We have state classes that we serialize with snapshots. But sometimes those state classes change, which makes reading snapshot fail obviously. We manage it by deleting those changed snapshots:
delete from snapshot sn
where sn.persistence_id::uuid in (select id from some_entity_table);
But for entities with a lot of events, when sending a new command, it takes a lot of time to get to the latest snapshot, resulting in timeout.
Would it be possible to force a rebuild of snapshots at the startup of the application?
Upvotes: 0
Views: 257
Reputation: 20561
Arguably the "true" solution to this is to use a SerializerWithStringManifest
which can deserialize the previous snapshot formats into the current format. If using reflection-driven serialization, this may be more difficult. It also won't migrate the existing snapshots.
One trick you can do is add an explicit ForceSnapshot
command into your persistent actor's protocol. This is pretty easy in the Classic API, where you have more control over snapshotting, so I won't go over that. In the EventSourcedBehavior
Typed API, however, this requires a bit more subtlety with adding a SnapshotForced
event and changing the snapshotWhen
function to return true
if the event is a SnapshotForced
.
Whether Classic or Typed, you can then have your application force every persistenceId to write a new snapshot by taking advantage of the currentPersistenceIds
Persistence Query:
val readJournal =
PersistenceQuery(system).readJournalFor[JdbcReadJournal](JdbcReadJournal.Identifier)
val everythingSnapshotted =
readJournal.currentPersistenceIds()
.mapAsync(parallelism) { id =>
// use the ask pattern to send a `ForceSnapshot` command and wait for reply
???
}
.runWith(Sink.ignore)
Upvotes: 0