Tags and keywords
A common challenge when dealing with sending and receiving of Signals in Magic Model Analyst® (Cameo Simulation Toolkit®) is synchronising things so that sent Signals don't go lost from the pool because a listening receiver is not ready. One way of preventing this is to use blocking callbacks (awaiting confirmation signals), but that doesn't always represent a real system well.
In the previous slide we saw how to handle a timeout for a send/receive using a TimeEvent on a Transition. One can also implement a timeout directly in an Activity, but fUML does not support InterruptibleActivityRegion, so a strategy for StructuredActivityNode is used instead:
Care has to be taken when using a TimeEvent for the timeout in parallel with an AcceptEventAction for the received Signal; if the TimeEvent completion and a Signal receive occur nearly at the same time, the timeout can disrupt the receive cycle. So a test against a flag value isReceived
is used to protect against inadvertent disruption of any receive processing cycle.
In the example the transmitter RandomTX
runs in a loop waiting for a random number of seconds between 0 and 10 seconds before sending a RandSig
.
The receiver TimeoutStructuredRX
uses an AcceptEventAction for RandSig
in parallel with a TimeEvent after (5 s)
within a StructuredActivity. Note how the value isReceived
is reset to False before it listens for RandSig
and to True immediately afterwards if the Signal is received. This value is then checked in a DecisionNode if the TimeEvent completes, and it will only end the StructuredActivity if isReceived
is False, otherwise it just goes to a FlowFinal. This ensures that if there is both a TimeEvent timeout AND a receive the receive cycle can complete.
Some other things to note about the example:
- Using Ports makes it easier to see in the simulation.
- The Operation
send
is under the explicit outer control ofDemoListenTimeoutStructured
; there is no classifier Behavior forRandomTX
. - The AcceptEventAction for
Repeat
is just a fallback to catch inadvertent context expiry during testing; if operating correctly it should never be reached. - The AcceptEventAction for
Interrupt
is just for "manual" testing.
This is a typical run console output. Note how the signal RandSig
is only received sometimes, and is more likely to go lost due to timeout when the wait time is longer:
00:00:00,000 : Initial solving ...
00:00:00,000 : Initial solving completed.
00:00:00,000 : **** Block DemoListenTimeoutStructured is initialized. **** 00:00:00,000 : **** Block DemoListenTimeoutStructured behavior is started! ****
RX: Listening...
TX: Wait (s): 5.932662590173026
RX: Timeout!
TX: Send!
RX: Listening...
00:00:13,164 WARN: the signal RandSig has not been consumed and removed from the TimeoutStructuredRX@68d44b26 pool
TX: Wait (s): 1.871352440546472
TX: Send!
RX: Timeout!
00:00:21,268 WARN: the signal RandSig has not been consumed and removed from the TimeoutStructuredRX@68d44b26 pool
TX: Wait (s): 7.703655454474811
RX: Listening...
RX: Timeout!
TX: Send!
00:00:32,442 WARN: the signal RandSig has not been consumed and removed from the TimeoutStructuredRX@68d44b26 pool
RX: Listening...
TX: Wait (s): 4.488153852903579
RX: Timeout!
TX: Send!
00:00:41,766 WARN: the signal RandSig has not been consumed and removed from the TimeoutStructuredRX@68d44b26 pool
RX: Listening...
TX: Wait (s): 1.13842091895773
TX: Send!
RX: Timeout!
RX: Received
TX: Wait (s): 0.15794000973120892
TX: Send!
00:00:52,786 WARN: the signal RandSig has not been consumed and removed from the TimeoutStructuredRX@68d44b26 pool
RX: Listening...
TX: Wait (s): 9.363841782576829
RX: Timeout!
RX: Listening...
TX: Send!
RX: Received
TX: Wait (s): 4.26224495323145
RX: Listening...
TX: Send!
RX: Received
TX: Wait (s): 1.0979079324447516
TX: Send! RX: Listening...
RX: Received
TX: Wait (s): 0.7485406645919357
TX: Send!
RX: Listening...
00:01:27,639 WARN: the signal RandSig has not been consumed and removed from the TimeoutStructuredRX@68d44b26 pool
TX: Wait (s): 0.5249661144028084
TX: Send!
RX: Timeout!
TX: Wait (s): 5.978946468973495
00:01:37,169 : **** Activity DemoListenTimeoutStructured execution is terminated. ****
00:01:37,171 : **** Block DemoListenTimeoutStructured execution is terminated. ****