Initial execution of an activity is not run-to-completion
Legacy Issue Number: 19679
Source: Model Driven Solutions ( Ed Seidewitz)
When an activity accepts an event, its execution proceeds as a “run-to-completion step”, and any new event occurrences (signal instances) are saved in the event pool and not dispatched until after the completion of the step. However, when an activity first starts executing (asynchronously), it is NOT in a run-to-completion step before it waits for the first time at an accept event action. This means that, during this time, any event occurrences that arrive could potentially be dispatched immediately and lost. Further, even if the first action to be executed in an activity is an accept event action, the specification would allow an execution trace in which all event occurrences happened before the action fired for the first time, meaning that, currently, it can never be ensured that an activity will be able to accept any event occurrences at all.
Rather than having the ClassifierBehaviorExecutionActivity start asynchronously from the EventDispatchLoop of the object activation for the context object, the EventDispatchLoop should make a synchronous call to execute the initial classifier behavior execution, and then only start looping once the initial execution completes. Note that the equivalent behavior should also be specified for bUML, so that the ArrivalSignal instances sent to an object activation are properly queued while the EventDispatchLoop is waiting for the initial classifier behavior execution to complete.
Reported: FUML 1.1 — Fri, 12 Dec 2014 05:00 GMT
Disposition: Resolved — FUML 1.2
Invoke classifier behaviors from the event dispatch loop
The UML 2.5 specification calls the initial event that starts the execution of a behavior the "event of its invocation". Essentially, what is required to resolve this issue is for such an invocation event occurrence to be handled as a run-to-completion step in the behavior execution, just as signal event occurrences are currently handled. A particularly direct way to do this would be to explicitly model invocation event occurrences, place them in the event pool for the context object of the behavior being (asynchronously) invoked and then having them dispatched and accepted using the current event loop and run-to-completion mechanisms.
Doing this would also manage the case of a context object with multiple classifier behavior executions that don't all start at the same time. This can happen if the object has multiple types with classifier behaviors. If the object is the target value for a start object behavior action whose object input pin is explicitly typed by one of the relevant classes, than only the classifier behavior associated with that class is started, even if the object has other types with classifier behaviors (in contrast, if the object pin is untyped, then classifier behaviors are started for all the object's types that have them; see the definition of the ObjectActivation::startBehavior operation in 126.96.36.199.5 of the fUML 1.1 specification).
This means that, when a classifier behavior execution is started, this may happen after other classifier behavior executions have already started and are already handling incoming (signal) event occurrences. Thus, the new invocation could happen when there are already event occurrences in the event pool waiting to happen and even possibly when there is already an ongoing run-to-completion step happening for a previously dispatched event occurrence. By explicitly modeling the invocation event occurrence for the new classifier behavior, the invocation can be managed in the same way as other event occurrences, by being placed in the event pool and eventually dispatched and handled in a run-to-completion step for the initial execution of the classifier behavior.
Finally, this approach provides an opportunity to generalize the model of the event pool to contain event occurrences other than signal instances. This will likely be eventually necessary anyway, in order to allow future specifications to incorporate the handling of other kinds of events into the fUML Common Behaviors framework (such as call events for state machines).
So, the proposal to resolve this issue is as follows:
- Create a new abstract EventOccurrence class, with a concrete SignalEventOccurrence subclass that has a reference to a SignalInstance.
- Generalize the eventPool to contain EventOccurrences instead of just SignalInstances.
- Create a new InvocationEventOccurrence subclass of EventOccurrence with a reference to an Execution being invoked.
- Change the ObjectActivation::startObjectBehavior operation to create an InvocationEventOccurrence and place it into the eventPool, rather than directly initiating the asynchronous execution of a behavior.
- Change the ClassifierBehaviorExecution class to ClassifierBehaviorInvocationEventAccepter, an EventAccepter that registers itself to match the InvocationEventOccurrence for a specific behavior Execution and, when it accepts a matching InvocationEventOccurrence, runs that Execution as a run-to-completion step.
Updated: Tue, 22 Dec 2015 15:09 GMT