You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
- Expand docs/processing_model.md with macrostep/microstep definitions,
event queues (internal vs external), processing loop diagram, and
continuous machine examples (raise_() chaining, eventless self-loops).
- Add "Cleanup / finalize pattern" section to docs/statecharts.md showing
that after_<event>() acts as a natural finalize with error_on_execution.
- Document raise_() vs send() in docs/transitions.md with "External vs
internal events" section and fix triggering-events Sphinx anchor.
- Improve raise_() docstring in statemachine.py with corrected cross-ref.
- Add statechart_cleanup_machine.py sphinx-gallery example demonstrating
both success and failure paths with automatic error recovery.
- Update AGENTS.md with processing model, error handling, eventless
transitions, and callback conventions.
> All state machine formalisms, including UML state machines, universally assume that a state machine
8
10
> completes processing of each event before it can start processing the next event. This model of
9
11
> execution is called run to completion, or RTC.
10
12
11
-
The main point is: What should happen if the state machine triggers nested events while processing a parent event?
13
+
The main point is: What should happen if the state machine triggers nested events while
14
+
processing a parent event?
12
15
13
-
This library atheres to the {ref}`RTC model` to be compliant with the specs, where the {ref}`event` is put on a
14
-
queue before processing.
16
+
This library adheres to the {ref}`RTC model <rtc-model>` to be compliant with the specs, where
17
+
the {ref}`event` is put on a queue before processing.
15
18
16
19
Consider this state machine:
17
20
@@ -45,14 +48,20 @@ Consider this state machine:
45
48
46
49
```
47
50
51
+
(rtc-model)=
52
+
48
53
## RTC model
49
54
50
-
In a run-to-completion (RTC) processing model (**default**), the state machine executes each event to completion before processing the next event. This means that the state machine completes all the actions associated with an event before moving on to the next event. This guarantees that the system is always in a consistent state.
55
+
In a run-to-completion (RTC) processing model (**default**), the state machine executes each
56
+
event to completion before processing the next event. This means that the state machine
57
+
completes all the actions associated with an event before moving on to the next event. This
58
+
guarantees that the system is always in a consistent state.
51
59
52
60
Internally, the events are put on a queue before processing.
53
61
54
62
```{note}
55
-
While processing the queue items, if others events are generated, they will be processed sequentially in FIFO order.
63
+
While processing the queue items, if other events are generated, they will be processed
64
+
sequentially in FIFO order.
56
65
```
57
66
58
67
Running the above state machine will give these results:
@@ -75,5 +84,214 @@ after 'connection_succeed' from 'connecting' to 'connected'
75
84
```
76
85
77
86
```{note}
78
-
Note that the events `connect` and `connection_succeed` are executed sequentially, and the `connect.after` runs on the expected order.
87
+
Note that the events `connect` and `connection_succeed` are executed sequentially, and the
88
+
`connect.after` runs in the expected order.
89
+
```
90
+
91
+
92
+
(macrostep-microstep)=
93
+
94
+
## Macrosteps and microsteps
95
+
96
+
The processing loop is organized into two levels: **macrosteps** and **microsteps**.
97
+
Understanding these concepts is key to predicting how the engine processes events,
98
+
especially with {ref}`eventless transitions <eventless>`, internal events
99
+
({func}`raise_() <StateMachine.raise_>`), and {ref}`error.execution <error-execution>`.
100
+
101
+
### Microstep
102
+
103
+
A **microstep** is the smallest unit of processing. It takes a set of enabled transitions
104
+
and executes them atomically:
105
+
106
+
1. Run `before` callbacks.
107
+
2. Exit source states (run `on_exit` callbacks).
108
+
3. Execute transition actions (`on` callbacks).
109
+
4. Enter target states (run `on_enter` callbacks).
110
+
5. Run `after` callbacks.
111
+
112
+
If an error occurs during steps 1–4 and `error_on_execution` is enabled, the error is
113
+
caught at the **block level** — meaning remaining actions in that block are skipped, but
114
+
the microstep continues and `after` callbacks still run (see
0 commit comments