The ‘external’ keyword is a modifier for requires interfaces of a component. Marking an interface as ‘external’ will increase its set of possible event sequences in the verification and simulation tools of Dezyne. More specifically, indicating that a requires interface is ‘external’ tells Dezyne that it should account for delays that can occur in communication through the interface. If the interface is stateful, this means that the two components on either end of the interface can get out of sync regarding the state of the protocol they use to communicate.
In the example with ITimer in the previous section, the Controller considers the state of Timer is Running when the cancel event is sent. However, the Timer has already timed out and has queued the timeout event accordingly. This is a textbook example of two components, Controller and Timer, being out of sync in regard to their perceived state of the protocol they use to communicate (ITimer). The result is that an unsuspecting Controller still receives a timeout it must handle even though the Controller is under the assumption that the Timer had been canceled.
If you modify the ITimer port of the Controller to requires external ITimer iTimer; and verify the Controller, you will actually find the illegal assert:
So, when should you use ‘external’? Right now, it might seem tempting to make every required port that sends out events ‘external’. However, its usage is not always warranted and as such you might be doing a lot of work for no benefit at all. The general rule of thumb:
Mark as ‘external’ any requires interface containing out-events that is delegated to the boundary of a system. Take note that the ‘external’ marking must be done in a behavior component, not a system component.
If a requires interface with out-events is implemented in a Dezyne component contained in the same system, the scheduling of said out-events will be done on the private Dezyne thread during runtime. The semantics enforced by the included Dezyne runtime simply prevent the component from scheduling any out-events while another component is executing its behaviour. Therefore, no race conditions between state and asynchronous events within the generated Dezyne framework can exist.
For more information on the Dezyne runtime semantics, please refer to https://www.verum.com/supportitem/execution-semantics/.
With proper inclusion of ‘external’ for components implemented outside of Dezyne, verification and simulation will once again consider the full scope of the possible behaviours of your application. As you saw in the previous sequence view, though, you have some work to do in the Controller component so that it can function correctly with an ‘external’ ITimer port. In the next section, we will explore some changes you can make to the implementation of a component to allow for ‘external’ behaviour.