eventsdomain-driven-designevent-sourcingsagaprocess-management

Should this Process Manager state be persisted?


I am developing an event-sourced Electric Vehicle Charging Station Management System, which is connected to several Charging Stations. In this domain, I've come up with an aggregate for the Charging Station, which includes the internal state of the Charging Station(whether it is connected, the internal state of its Connectors).

The commands I can issue to a Station aggregate are:

And I've come up with another aggregate which represents the Charging Session, the interaction between a User and a Charging Station's Connector. The creation of a Charging Session is coupled with these events, i.e. if the Connector has been unlocked by a user, a session was created, if the Connector's energy flow has stopped, the Charging Session has finished.

I've added a Process Manager that listens to the events:

for the first event, it's pretty straight-forward to create the session. However for the latter, it must know the sessionID of the ongoing session happening on the Connector(connectorID) of the Station(stationID), so it can update the session.

I can't simply implement a GetSessionByConnectorID function as I'm implementing an event-sourced system, and the only way I can get the event stream of a session, is by its ID, not by its ConnectorID(because I only know the session's ConnectorID when I hydrate it back), so I don't see how I could implement the GetSessionByConnectorID function.

So, the process manager has some internal in-memory state((stationID, connectorID) -> (sessionID)), to keep track of the sessionID. However, as it is in-memory, as soon as the process manager crashes, I've lost the association between the (stationID, connectorID) <-> (sessionID) and I can no longer respond properly to the ConnectorEnergyFlowStopped event.

session-flow

How should I handle that? Should I persist the Process Manager state? Should I persist it with Process Manager events(which would be awkward since, it does not correlate nicely with the Ubiquitous Language, i'm thinking SessionProcessManagerReceivedStationConnectorUnlockedEvent-awkward-level)

Edit - new thought

I thought about something else, which would be to remove the internal Process Manager state, and put the association of the (stationID, connectorID) <-> (sessionID), inside of the Station aggregate. That would, unfortunately, mean a higher coupling(the Station must know when a session is Created, and how to generate its ID), but I think it could be simpler(as the Station's events are persisted). So the Station would emit the session-related events, with the sessionID inside of them:

However, it does seem a bit odd to mix the two things, even if it's just the ID of the session.


Solution

  • I can see quite a few ways of solving this but I am not familiar with your domain, so just throwing ideas here:

    If possible, I'd go with the second one. The last one would be second in my list and the process manager would be the last resort due to the associated complexity.