I’m using Lagom to model changes in an entity that closely resembles an FSM (I’m sure a common use pattern). Since the FSM has terminal states, after which no change to the entity is possible, what I’d like to do is to stick a “guard action” at the top of the Behaviour chain to prevent any modifications, something like:
override def behavior: Behavior = {
// Don't do anything to entities in a terminal state
case Some(entity) if entity.inTerminalState =>
new TerminalStateActions()
case Some(entity) =>
// .. model my entity here
}
An implementation of TerminalStateActions might be as simple as:
class TerminalStateActions() extends Actions(Map.empty, Map.empty.withDefaultValue{ case (cmd, ctx, st) =>
ctx.commandFailed(new ModifyEntityInTerminalStateException("Can't modify this entity"))
ctx.done
})
Tying to implement this myself, I was stymied by the fact that Actions.commandHandlers
is a Map[Class[_], CommandHandler]
and CommandHandler
is private[lagom]
, meaning I can’t do this without hacks.
So I guess I have two questions:
- Is this an anti-pattern that Lagom is deliberately not letting me fall into? If so, what’s the general shape of the pattern?
- If that’s not the case, what’s a good way to implement terminal states in an FSM - ones which can’t be exited from - without having to add a no-op command handler every time I add a message?
Many thanks!