Add CallEvent, AcceptCallAction and ReplyAction
To disallow the use of methods to implement operations, as suggested in the issue description, would be a major backward incompatibility with previous versions of fUML and a radical departure from typical object-oriented practice. It would also essentially require all classes to be active, since only active objects have event pools and can react to event occurrences. Finally, it would require that the fUML execution model be completely rewritten, along with its base semantics, since it currently uses an OO style in which (concrete) operations always have methods.
On the other hand, the Precise Semantics of State Machines (PSSM) specification (as submitted) adds the ability for state machines to handle call events, as an alternative to, not a replacement for, using methods to implement operations. But the generic handling of operations via call events (as described in the UML 2.4.1/2.5 semantics) is not really specific to state machines. So it is reasonable to suggest that this capability would be better incorporated into the common behavior semantics of fUML, rather than only being available when a tool conforms to PSSM.
Indeed, the PSSM alpha specification gets around the lack of support for call events in the fUML common semantics by introducing a specialization of the RedefinitionBasedDispatchStrategy class that returns a special kind of Execution when a call is to be handled using a call event. However, this means that any tool using an alternative dispatch strategy would also need to have a specialization of that strategy that is similarly modified to be able to handle calls using call events – but only for use when PSSM is supported. It would clearly be better if any properly specified dispatch strategy would automatically work whether a call ended up being handled by a method or by a call event occurrence.
Further, the PSSM alpha specification uses a "spin loop" (i.e., a loop that continually checks the value of a semaphore, which is expected to be reset by a concurrent process) to specify the blocking of a caller while it waits for a call event occurrence to be handled by the target object. This is problematic, since the fUML concurrency semantics do not guarantee that any one executing process allow any other process to execute, except at a "wait point" (such as an accept event action). This means that, as currently specified in PSSM, it would be a legal execution trace for a "blocked" caller to continually execute its loop, without allowing the target object classifier behavior to ever execute to handle the call event occurrence, so the call would never complete.
Any alternative to using a "spin loop" blocking approach would need to be incorporated directly into the fUML common behavior semantics. Unfortunately, to do so would require a major change to the handling of synchronous calls in general. This is because, even if a behavior is itself invoked directly, whether via a direct call or as an operation method, it could (directly or indirectly) call an operation that is handled using a call event occurrence. Thus, the execution model would have to take into account that, on any call action or other synchronous behavior execution, the call might have to block for an arbitrarily long amount of time (or forever), waiting while some call event occurrence remains unhandled.
One way to handle this would be by specifying that output parameter values from any behavior execution be delivered via a "call back" mechanism. A caller would provide a "continuation" object when calling the execute operation on the behavior execution, and output parameter values from the invocation would be delivered by calling an operation on the provided object, rather than being set during the running of execute itself. Thus, if the call gets blocked waiting for the handling of a call event occurrence, the original execute call could return, with the caller only continuing once a call back is made to its continuation object (if ever).
But this would be a major change to the fundamental approach for handling synchronous invocation in the fUML execution model, all the way up to the event accepter mechanism (since a run-to-completion step is essentially specified in the fUML execution model by making a synchronous call to an event accepter). And this would not only complicate the specification of fUML, it would also make it significantly more complicated to handle, e.g., the invocation of entry, exit and effect behaviors on state machines in PSSM. It is therefore not considered feasible to propose this approach in the context of an RTF issue resolution.
Another possibility would be to introduce a mechanism into the base semantics, that is, the formal semantics of Base UML (bUML), in which the fUML execution model is written. However, in order to do this, it would be necessary to also extend bUML syntactically with a UML feature that could represent such blocking. For example, an accept event action could be used with a trigger for a change event on a semaphore attribute (which would avoid the need for a spin loop) or for a time event (which would allow a caller to "wait" for some period of time during an iteration of a spin loop, allowing other processes to execute).
But one of the fundamental tenets of bUML is that it is a syntactic subset of fUML – that is, the fUML execution model is itself a legal fUML model. That means that any new feature introduced into bUML would also need to be introduced into fUML. But both change events and time events have not been incorporated into fUML so far because of the difficulty in specifying their (general) functionality. So, again, it is not considered appropriate to attempt introducing this functionality simply to address an issue that did not even request that functionality specifically.
Therefore, while this resolution does propose adding CallEvent, AcceptCallAction and ReplyAction to fUML, it specifies their semantics using an approach similar to that in the PSSM alpha specification, using a spin loop. However, a requirement is added, without further formal basis, that an execution trace that consists entirely of a caller executing a spin loop for all time is not allowed, unless no other execution trace is possible (i.e., no other non-blocked concurrent processes are available to execute). It is considered clear that this can be implemented in practice in any execution tool, evn in the absence of further formalization. However, it is also expected that the requirement will be more formally specified in a future major revision of fUML.