This material might be a bit small, rough, and obvious for an article. It's also purely theoretical, speculative, and it doesn't have code. Nevertheless, I've decided to put it up on CodeProject to get feedback. It could be expanded or moved into my blog on CodeProject, or rolled into a larger article about concurrent state machines. Working title was: "UML Joins are evil".
Interestingly, I couldn't find a readily available (commercial or Open-Source) state machine (SM) framework that would have an explicit implementation of Joins. Synchronization between concurrent regions with messages is pretty common, and Joins can be done implicitly. Not every SM framework supports orthogonal regions, but I haven't seen a single one that would have Join objects, for example. If you know of one - please point me to it.
Are Joins pseudostates in UML? Is the semantics of a Join well defined? How should it be used?
State: The state machine (SM) should be in a state to be able to handle messages. If there's a message that needs to be received and serviced by the SM within a certain period, that sets the upper threshold for a "considerable amount of time". An obvious corollary: transitions between states should be atomic.
Pseudostate: I couldn't find a rigorous definition of a pseudostate. For now, let's assume that, since they aren't states, the SM doesn't spend a considerable amount of time in pseudostates.
1. Statechart for the example
- The state machine in this example has two concurrent regions (Channel 1 and Channel 2).
- State S11 reacts to message M3 by making a transition T1.
- States S21 and S22 react to M2 internally, by design; Channel 2 always has to react to M2.
- S21 also reacts to M1 by making a transition T2.
- Because of the fork F1 and Join J1, the complete transition from S21 to S22 is impossible until T1 has been made.
Nice picture! It's a topological diagram where time (or any other coordinate) is not defined. However, we can come up with a scenario and make a timeline for it, as in Figure 2.
- M1 arrives first, state S21 makes a transition T2 and now is stuck on J1.
- M2 arrives, but Channel 2 doesn't have a state, and it can't service the message. This is the problem.
The solution, actually, is simple - the Join should reside in the contexts of the states that it originates from. Can we still call Join a pseudostate?
[OMG 07] OMG Unified Modeling Language (OMG UML), Superstructure, V2.1.2
- 0.1: Initial draft: Feb. 15, 2009.