Re: History transition executable content - when is it executed?

I agree that a using a table is cleaner than hacking an attribute into 
state.  It is probably also cleaner to pass it as an extra argument, 
though we do use a number of globals in the algorithm already.  As long 
as the extra argument is used in only a  few places and _none_ of the 
other entry/exit logic changes, it's a safe change.

For the prose in the spec, I am thinking of adding something like the 
following in 3.10.2, right after the penultimate sentence (which is "If 
it has not, the SCXML processor /MUST/ behave as if the transition had 
taken the default stored state configuration for that history state as 
its target"):

The Process MUST execute any executable content in the transition after 
the history pseudo-state's parent state's onentry handlers, and, in the 
case where the history pseudo-state was the target of an <initial> 
transition, after any executable content in the <initial> transition.

Let's wait a couple of days to see if there are any other comments. Then 
I will update the editor's draft and send around a link to it so that 
people can have a look.  There won't be a new public draft until we go 
through the publication procedure, which will take a couple of weeks.

- Jim


On 3/25/2014 2:42 AM, Ate Douma wrote:
> On 24-03-14 21:40, Jim Barnett wrote:
>> I have looked at this and think it's a nasty bug in the spec.  As far 
>> as I can see, the algorithm never executes the executable content 
>> inside a history state's transition child.  (Somebody please tell me 
>> if I'm wrong - it will save us a lot of time.)  Furthermore the text 
>> of the specification does not specify when such executable content is 
>> to be executed.
>>
>> If the bug is as serious as I think, the fix will involve changes to 
>> the normative language of the specification and we will have to go 
>> back to Last Call again.  Furthermore, I don't see a clean way to fix 
>> the algorithm because all trace of the fact that we're entering a 
>> history state is gone by the point in enterStates where executable 
>> content is executed.  I see several possible solutions, and am open 
>> to others:
>>
>> 1.  Forbid executable content in the <transition> inside history.  I 
>> know that there's good reason to allow it there, but I mention this 
>> because it is the smallest possible change to the specification that 
>> restores correctness.  However it weakens the language and leaves us 
>> with a transition element that has no motivation.
>>
>> 2.  Get rid of the transition and add an 'defaultInitial' attribute 
>> to the history state.  This is basically the same idea as 1, but it 
>> fixes the syntax.  There would be only one trivial change to the 
>> algorithm - we would take the default history configuration from the 
>> history state's  defaultInitial attribute rather than from the target 
>> of its child transition.  But it still weakens the expressiveness of 
>> the language.
>>
>> 3.  Try to fix the algorithm so that it executes the content in the 
>> transition.  To avoid breaking anything else, this change should be 
>> as small and as isolated as possible.  What I've come up with so far 
>> is to kluge a 'extraContent' attribute onto a state.  Then in 
>> addDescendantStatesToEnter we would modify the clause that handles 
>> the default transition so that it also appends the transition's 
>> executable content to the parent state's extraContent attribute (that 
>> is, to the parent state of the history state).  Then in enterStates 
>> right after we execute a state's onentry content, we would execute 
>> its extraContent and then set it to null. This is aesthetically 
>> unsatisfying, to say the least, but seems safer than trying to 
>> rejuggle a bunch of definitions to handle things cleanly.
>>
>> Please send me your thoughts on this. All options are ugly, but I 
>> think that we have to do something.
>
> I agree this should be properly fixed in the algorithm, but I dislike 
> kludging some extra attribute on a state object for the duration and 
> scope of one micro step only. If possible I'd keep the SCXML element 
> model definitions independent of current execution state and context.
>
> A maybe cleaner way to do is to introduce and use a temporary 
> table<State.id,Transition> data structure and use that to keep track 
> and look up the History transition to be executed when entering a state.
> This table then only is needed and used in the scope of the 
> enterState() procedure:
>
>   procedure enterStates(enabledTransitions):
>       statesToEnter = new OrderedSet()
>       statesForDefaultEntry = new OrderedSet()
>       // initialize the temporary table for targeted History transitions
>       defaultHistoryTransitionOnEntry = new HashTable()
>       // pass on this table to computeEntrySet
>       computeEntrySet(enabledTransitions, statesToEnter, 
> statesForDefaultEntry, defaultHistoryTransitionOnEntry)
>       for s in statesToEnter.toList().sort(entryOrder):
>           configuration.add(s)
>           statesToInvoke.add(s)
>           if binding == "late" and s.isFirstEntry:
>               initializeDataModel(datamodel.s,doc.s)
>               s.isFirstEntry = false
>           for content in s.onentry:
>               executeContent(content)
>           if statesForDefaultEntry.isMember(s):
>               executeContent(s.initial.transition)
>           // if this State is a parent of a targeted History, now 
> execute the History transition executable content (if any)
>           if defaultHistoryTransitionOnEntry[s.id]
>               executeContent(defaultHistoryTransitionOnEntry[s.id]
>       ...
>
> This table also will have to be passed on from computeEntrySet(), 
> addAncestorStatesToEnter() and addDescendantStatesToEnter() 
> (recursively), and the latter then is modified like:
>
>   procedure 
> addDescendantStatesToEnter(state,statesToEnter,statesForDefaultEntry, 
> defaultHistoryTransitionOnEntry):
>       if isHistoryState(state):
>           if historyValue[state.id]:
>               // track this targeted History its transition on its 
> parent state id for processing in enterStates() after entering its parent
>               defaultHistoryTransitionOnEntry[state.parent.id] = 
> state.transition
>       ....
>
> Alternatively, the defaultHistoryTransitionOnEntry table can be 
> defined global and initialized in procedure interpret() so as not 
> having to modify the signatures of any of these procedures, but then 
> you probably also will want to clear/reset this table in enterState() 
> and assert its empty afterwards as it only is used within its context. 
> You only need to modify the *body* of the interpret(), enterStates() 
> and addDescendantsStatesToEnter() procedures then.
>
> I prefer the first solution though as it is more clean and clear, the 
> second solution only to be considered to minimize the impact of the 
> change.
>
> Note also I put the History transition handling after its parent 
> initial.transition handling explicitly, as the parent.initial might 
> actually be the one which targeted the History. Therefore their 
> execution order is significant.
>
> Ate
>
>>
>> - Jim
>>
>> -----Original Message-----
>> From: Ate Douma [mailto:ate@douma.nu]
>> Sent: Monday, March 24, 2014 4:20 PM
>> To: www-voice@w3.org
>> Subject: History transition executable content - when is it executed?
>>
>> While implementing the SCXML Algorithm, I noticed the 
>> handling/processing of executable content of a History transition 
>> isn't taken care of yet.
>> Neither in the Algorithm nor in wording (when) in the specification.
>>
>> The addDescendantStatesToEnter procedure dereferences History states, 
>> so these History states correctly don't end up in the statesToEnter, 
>> but then neither will their possible transition executable content be 
>> processed.
>>
>> And as important: when should History transition executable content 
>> be processed?
>>
>> It seems like an obvious choice that it should happen after the 
>> History parent state onentry and before any History default targets 
>> onentry execution.
>>
>> Any opinions?
>>
>> At any rate, I think this needs to be clarified in the specification, 
>> and also integrated in the Algorithm.
>>
>> Kind regards,
>> Ate
>>
>>
>
>

-- 
Jim Barnett
Genesys

Received on Tuesday, 25 March 2014 13:26:50 UTC