provide interface or options allowing interpreter context to set execution limits
Created by: mattoshry
The purpose is to detect/prevent an FSM that has spun out of control.
Primary limits that come to mind:
- execution time per big step
- max count per event name
Consider treating 'error' events (error, error.*) as special / single bucket with its own limit. Consider observing/limiting unhandled event count
Provide an interface to inform/notify the interpreter context when one of these limits has been exceeded so that the context can take appropriate action (e.g. terminate the session).
Here are a few bad scxml documents:
- infinite raise
- infinite send #_internal
- infinite send #_scxml_
<scxml xmlns="http://www.w3.org/2005/07/scxml"
version="1.0"
initial="uber">
<datamodel>
<data id="count" expr="0"/>
</datamodel>
<state id="uber">
<transition event="loop" target="s1"/>
<transition event="*">
<log expr="'Ignoring unhandled input ' + JSON.stringify(_event)" label="TEST"/>
</transition>
<state id="s1">
<onentry>
<assign location="count" expr="count+1"/>
<if cond="!count">
<log expr="'Starting session ' + _sessionid" label="TEST"/>
<else/>
<log expr="'Re-entering s1 with count: ' + count" label="TEST"/>
</if>
<raise event="loop"/>
</onentry>
</state>
</state>
</scxml>
<scxml xmlns="http://www.w3.org/2005/07/scxml"
version="1.0"
initial="uber">
<datamodel>
<data id="count" expr="0"/>
</datamodel>
<state id="uber">
<transition event="loop" target="s1"/>
<transition event="*">
<log expr="'Ignoring unhandled input ' + JSON.stringify(_event)" label="TEST"/>
</transition>
<state id="s1">
<onentry>
<assign location="count" expr="count+1"/>
<if cond="!count">
<log expr="'Starting session ' + _sessionid" label="TEST"/>
<else/>
<log expr="'Re-entering s1 with count: ' + count" label="TEST"/>
</if>
<send target="#_internal" event="loop"/>
</onentry>
</state>
</state>
</scxml>
<scxml xmlns="http://www.w3.org/2005/07/scxml"
version="1.0"
initial="uber">
<datamodel>
<data id="count" expr="0"/>
</datamodel>
<state id="uber">
<transition event="loop" target="s1"/>
<transition event="*">
<log expr="'Ignoring unhandled input ' + JSON.stringify(_event)" label="TEST"/>
</transition>
<state id="s1">
<onentry>
<assign location="count" expr="count+1"/>
<if cond="!count">
<log expr="'Starting session ' + _sessionid" label="TEST"/>
<else/>
<log expr="'Re-entering s1 with count: ' + count" label="TEST"/>
</if>
<send type="http://www.w3.org/TR/scxml/#SCXMLEventProcessor"
targetexpr="'#_scxml_' + _sessionid" event="loop"/>
</onentry>
</state>
</state>
</scxml>