A finite state machine composition library.
The library is built on composing FSM's with well defined initial and final states. The FSM's are built using Pallet-fsm, a library for constructing arbitrary finite state machines.
The fsm's that can be composed should have an :init initial state, and should respond to the :start event. They should have :completed, :failed, :aborted, and maybe :timed-out as terminal states.
Wondering why you might want to use this? See the rationale.
FSM's are built as functions, and then executed using the
which returns a data-structure. The return data-structure can be deref'd to
block until completion.
The library comes with a comprehension
dofsm for building FSMs. In this first
example, we use the
result FSM function, which takes a non-FSM value and
creates a FSM that returns it.
(let [op (fn [v] (dofsm my-calc [x (result 1) x (result (+ x 2))] x)) op (operate (op :ok))] @op ; => 3 (complete? op) ; => true (failed? op) ; => nil
dofsm takes a name, a sequence of result and FSM config bindings and a result
expression. It returns a FSM specification that can be run by
Other built-in fsms are
Higher order FSMs
The library also provides higher order fsm's. The
timeout form adds a timeout
to another fsm.
(let [op (fn [delay-length] (dofsm delay-op [_ (timeout (delay-for delay-length :ms) 500 :ms)] _)) op (operate (op 500))] @op)
The code above will time-out, if passed a delay-length greater than 500ms.
Other higher order FSMs are
map*, that will run a sequence of fsm's in
parallel and wait for them to all complete, and
reduce*, that will thread
results through a sequence of FSMs.
Running a FSM
A FSM configuration can be run by the
operate function. The function returns a
Operation object that can be used to obtain the state of the FSM operation
You can wait for the FSM to complete by
deref'ing the FSM operation, which
will re-throw any exceptions. You can also use
wait-for to wait. In the
later case, exceptions are reported on the
report-operation function can be used to inspect the state of an operation
that is running.
To use pallet-fsmop, add the following to your
Copyright © 2012 Hugo Duncan
Distributed under the Eclipse Public License.