Thanks a lot for your quick response @maxim!
Ah, that wasn’t obvious to me yet, and I’d have to look deeper into. I may still have to provide my own persistence layer then, both on the write- as well as on the read-side. OTOH maybe if, say, I have a UserAccount
domain aggregate that is controlled and accessed via an actor-like Workflow in the Application layer, then this workflow could be active for as long as the user account exists?
- Domain layer has no dependencies (inversion of control), guarantee valid (domain) state, and invocations raise events.
- Application layer has business logic which are mostly Workflows, Child Workflows + Activities.
- Domain events and domain errors trigger Signals in the Application layer to the running workflows.
- (Maybe) There’s no need for Repository interfaces in Domain layer, and DB impls in Infra layer. Temporal persistence is used.
The above may make no sense, not work. Shows my noobness on the paradigm shift that Temporal seems to offer. A safe architecture design would be to have the ports & adapters, DDD, CQRS/ES as I intended, but having Temporal only provide Saga capability and handle some clearly long-running tasks.
Yes, but the read-site of CQRS would offer denormalized views on the data. But I think you mean to say this is the way to get at workflow state for implementing the read-side, which then has its own way of dealing with persistence.
With imported / embedded I was referring to the Production deployment page stating “The Temporal Server is a Go application which you can import or run as a binary.” and then in my Go code calling s := temporal.NewServer()
to fully embed the server instead of having it separately deployed (e.g. via Docker, etc.). I was not referring to forking and extending, just invoke functionality as-is but have the server code fully encapsulated in my own application. Is that possible, or did I misinterpret?