Hey everyone!
I'm in the process of cracking event sourcing for DA for my needs (e.g. swift-chat), which then want to decouple and create a separate package out of it.
Here are a bit more information on the topic.
So far I'm trying to replicate Akka's EventSourcedBehavior, currently idea is that there will be a protocol:
public protocol EventSourced: Codable, DistributedActor where ActorSystem == ClusterSystem {
associatedtype State: Codable & Sendable
associatedtype Command: Codable & Sendable
associatedtype Event: Codable & Sendable
var state: State { get set }
var persistenceId: PersistenceId { get }
distributed func handle(command: Command) async throws -> Event
distributed func handle(event: Event) async throws
}
which then can be applied to actors, e.g.
distributed actor SomeActor: EventSourced {
struct State: Codable, Sendable {
mutating func change() {}
}
enum Event: Codable, Sendable {
case none
}
enum Command: Codable, Sendable {
case none
}
let persistenceId: PersistenceId = "Some"
var state: State = State()
distributed func handle(event: Event) { self.state.change() }
distributed func handle(command: Command) -> Event { Event.none }
}
(note: will continue on improving that, e.g. currently it's not obvious handle(event:) should be applied to state)
But here where I'm struggling a bit, cause in Akka you just call Effect.persist(event) and it will do trick for you to persist event. And as I don't have much experience in Akka—not even sure how it's implemented under the hood.
currently slowly reading the documentation and code.
What I have in my mind is that in order to declare EventSourced actors you should register EventJournal plugin (like it's done with ClusterSingletons) like $0.plugins.install(plugin: EventJournal(.postrgres(config))) with some magic behind. And then somehow declare func persist(event:) function for actor...
Another question I'm wondering about—I guess this also could be applied to non-distributed actors, where you can just create a separate journal in iOS/macOS/etc and add actors to it. ![]()
So if anyone have some suggestions or ideas—would be nice to hear. Also if someone can point to some article or implementation would be also nice to check.