Software engineers tend to think of (finite) state machines as a kind of intermediary interpreter. That is, you take a regular language and compile that into a state machine, then execute the state machine. The state machine itself is rarely visible to the developer: it’s an internal representation—optimized, compressed, and bizarre.
However, it turns out that state machines are also valuable as first-class modeling languages for protocol handlers, such as ØMQ clients and servers. ØMQ makes it rather easy to design protocols, but we’ve never defined a good pattern for writing those clients and servers properly.
A protocol has at least two levels:
How we represent individual messages on the wire
How messages flow between peers, and the significance of each message
We’ve seen in this chapter how to produce codecs that handle serialization. That’s a good start. But if we leave the second job to developers, that gives them a lot of room to interpret. As we make more ambitious protocols (file transfer + heartbeating + credit + authentication), it becomes less and less sane to try to implement clients and servers by hand.
Yes, people do this almost systematically. But the costs are high, and they’re avoidable. In this section I’ll explain how to model protocols using state machines, and how to generate neat and solid code from those models.
My initial experience with using state machines as a software construction tool dates back to 1985 and my first real job making tools for ...