commons-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Rahul Akolkar" <rahul.akol...@gmail.com>
Subject Re: [SCXML] SCXMLListener Exception Handling Question
Date Mon, 27 Mar 2006 07:11:59 GMT
Consolidating replies into one email ...

On 3/26/06, Jon Brule <tricolorcat@gmail.com> wrote:
> Good Morning,
>
> I am attempting to decouple state action code from the state machine's
> execution by using the SCXMLListener interface in non-inner classes (like
> StopWatch example)... Now suppose within a listener implementation I
> encounter a checked exception... Since the SCXMLListener interface does not
> account for checked exceptions, how best can I communicate this back to the
> state machine execution to alter the execution path, say to perform an
> automatic transition to an error state?
>
<snip/>

The SCXMLListener concept was primarily introduced to allow processes
to register for notifications for state machine execution events
(entry, exit, transition), fairly passively, without necessarily being
too entangled in the execution itself. Using SCXMLListeners in
non-inner classes is therefore suitable for managing "side-effects" of
state machine execution.

As an example, consider a content management system. We may have:

 * An SCXMLListener that sends out an email / page / text message to
an assigned reviewer when a document has been updated and needs to be
reviewed before it can be republished. Even if the communication
fails, that doesn't affect the "state" of the document (though
hopefully the SCXMLListener raises an appropriate alarm).

 * An SCXMLListener that maintains rejection data, logging number of
times reviewers have rejected changes, thereby trying to identify
trouble spots etc. Again, there could be glitches in doing so, but
they probably don't affect any document's state machine.

To your question, if you want feedback for checked exceptions, there
are many ways to do so (more below). Ofcourse, if the SCXMLListener is
an inner class for the class managing the state machine execution
(SCXMLExecutor instance), then it can actually take quite an "active"
role.


On 3/26/06, Jon Brule <tricolorcat@gmail.com> wrote:
> Or should I be using custom actions to accomplish this sort of
> decoupling? But if I throw a ModelException for some processing error,
> how does the statemachine handle this? Can I route all ModelExceptions
> to a particular error state?
>
<snap/>

Yes, custom actions offer one solution. A ModelException is meant to
be thrown if the underlying state machine becomes non-deterministic or
exhibits other serious flaws which make it impossible to proceed
beyond a certain point. A more useful mechanism than throwing a Java
exception is to catch the error condition / checked exception and fire
a derived error event on the state machine.

In the <my:action>'s execute() method:

// on error condition or checked exception
derivedEvents.add(new TriggerEvent("err.foo",
  TriggerEvent.ERROR_EVENT));

And the SCXML snippet:

<state id="foo">
  <onentry>
    <my:action ... />
  </onentry>
  <transition event="err.foo" target="errorstate" />
  <!-- other transitions etc. -->
</state>

Interestingly, there are numerous usage patterns that may be employed
effectively with Commons SCXML. In all usecases, we are dealing with
three things:

 * The "engine" - Commons SCXML, a generic event-driven state machine
based execution environment
 * The "domain" - The realization in software of the domain whose
behavior we've defined via SCXML document(s)
 * The "bridge" - The two way communication link, events flying from
domain to state machine engine and activities being triggered in
domain based on current states for the state machine

Here are some usage patterns for bridging (not a comprehensive list):

 * STATE TO ACTIVITY MAPPING USAGE PATTERN

This approach consists of maintaining some sort of lookup table that
tells us what we should *do* (i.e. the activity to be performed) when
we end up in a particular state. We fire events, query the executor
for current states, lookup what we need to do, and those activities
yield the next set of events moving us forward. Pattern is often
useful when:
  - The activities are homogeneous (we always activate a component of
a specific type or we always render a page and wait for submission
etc.)
  - We don't care about intermediate states (after an event is
triggered, we may transit through some states on the way, but we are
only interested in where the engine has "come to rest")
  - The "advanced" usecases on the website use this pattern, the RDC
usecase (dialog management in speech apps) implicitly maps state IDs
to IDs of speech components that get activated, and the Shale usecase
(cross-page navigation for JSF apps) has an explicit lookup table
mapping state IDs to JSF view IDs

 * SCXML LISTENER USAGE PATTERN

As discussed above, this is useful for:
  - Activities that have high likelihood of succeeding - such as UI updates
  - Managing side-effects
  - The StopWatch usecase uses this pattern
Usage as inner classes can expand scope of pattern to go beyond that,
including actively firing events on state machine.

 * SEND USAGE PATTERN

We can use the <send> element to "dispatch" an event of choice
(including whatever payload) to whatever targettype we provide
implementations for via a suitable EventDispatcher implementation. The
target then performs the activity needed to make progress.
  - For examples, see recent thread on send (from a day or two ago)

 * CUSTOM ACTIONS USAGE PATTERN

As discussed above, using custom actions in conjunction with derived
events leads to quite elegant authoring. Downside is having to author
custom actions. From a state machine theory point of view, actions are
supposed to take negligible amount of time, so if expensive operations
are being performed, that theory would recommend we use the <invoke>
pattern.

 * INVOKE USAGE PATTERN

The <invoke> element is defined by the latest version of the W3C SCXML
WD. It allows us to invoke processes from simple states (those that
don't have <parallel> or <state> children). It also specifies that the
process may return a payload with the "done" event, that becomes
available for decision making in the state machine context under a
special variable "_eventdata". One of the downsides to this pattern is
that it is *not* implemented in Commons SCXML ;-) However, there are
plans to add that soon (probably in a week).

Also, as I'm currently working on the user guide, any suggestions for
improvement you have about documentation (or otherwise) are most
welcome.

-Rahul


>
> Thanks,
> Jon
>
> --
> Jon Brule
> tricolorcat-at-gmail.com
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-user-help@jakarta.apache.org


Mime
View raw message