- A machine is a specification of transitions, states, etc. It is immutable.
- A state is, well, a state. It represents the state of some system at some
specific moment. It's also immutable.
How is the state different from the machine?
- The machine is like a map (a chart of locations & directions, not a
clojure map data structure). A map could indicate how one could go from one
place to another. Likewise, a machine indicates how a system could transition
from one state to another.
- The state is like a place on a map.
How is a machine like a map? The map itself is not in any place. It just
contains all the directions. Similarly, the machine itself is not in any state.
It just contains all the possible transitions.
The state itself (mainly) contains two piece of information:
- the current state value, e.g.
:connecting
, or [:connecting :handshake]
.
(see [Hierarchical States]({{< relref "docs/hierarchical-states.md" >}}) for
how to represent hierarchical states). - the current state context, e.g. number of seconds to back off before next
connection attempt.
The current state is expressed as a map like this:
{:_state :waiting
:user :jack
:backoff 3000}
- All keys that starts with an underscore (e.g.
_state
) is considered internal
to clj-statecharts. Application code could read them, but should not modify
them. - All others keys are application-specific data, collectively called the
"context"
of the state machine.
How are machine/state connected to the higher level services?
A service is stateful, and we need it for two reasons:
- We need a container of state to represent the state of system, which could
transition over time. Actually it's just an atom in the state record.
- For [delayed transitions]({{< relref "docs/delayed.md" >}}), we need someone
to keep track of these scheduling information. In its essence a delayed
transition is just a timer:
- the timer is scheduled when entering the state
- if the machine transitions out of the state before the timer is fired, the
timer shall be canceled.