Search code examples
state-machinescxml

Create a timeout in an SCXML state machine


In an SCXML state machine, how can I say "Fire an event 3 minutes after I enter this state, but not if I sit in the state for 2.9 minutes and then leave. If I re-enter the state, restart the timer (don't go off in 0.1 minutes)"


Solution

  • Use <send> to fire a delayed event (with any name, e.g. "timeout") when you enter the state, and use <cancel> when you exit the state to remove the timer. You must make sure that you create a unique ID for each <send> instance that you plan to later cancel.

    <scxml xmlns='http://www.w3.org/2005/07/scxml' version='1.0'>
      <state id="s1">
        <onentry><send id="state1-timer" event="timeout" delay="180s"/></onentry>
        <onexit><cancel sendid="state1-timer"/></onexit>
      </state>
      <!-- ... --->
    </scxml>
    

    Note: you can only use either s (seconds) or ms (milliseconds) for the delay duration, per the CSS2 time spec. Thus, 3 minutes is 180s.