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. There are many other ways of handling it; this shows just one approach, a TimeEvent on a Transition for a timeout, and a carefully organised outer Transition loop to reset the listener.
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 TimeoutRX
uses a StateMachine, which is critical to the strategy, because the 'doActivity' doListen
on the state Listening
can be "interrupted" by a Transition with a TimeEvent after (5 s)
and Transition to a state TimedOut
.
There are nevertheless ways of achieving interrupting a StructuredActivityNode, but in the strategy shown here a TimeEvent on a Transition is used.
A ResetListen
send from doListen
ensures the context does not simply expire (in which case the timeout Transition to state TimedOut
would eventually be taken, although one could instead include a guard on the Transition to state TimedOut
).
Note also that doListen
does NOT loop, rather the strategy relies on outer control via the StateMachine for TimeoutRX
.
Use of a distinct state Resetting
state makes it easier to follow in the simulation (one could instead just use a Transition to self for signal ResetListen
).
If the StateMachine for TimeoutRX
is in state Resetting
or state TimeOut
when a RandSig
is sent, the signal may go lost. Note that there is a wait of 1 second before state TimeOut
transitions to state Resetting
, and a wait of 1 second before state Resetting
transitions back to state Listening
.
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 ofDemoListenTimeout
; 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.
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 completed.
00:00:00,000 : **** Block DemoListenTimeout is initialized. ****
00:00:00,000 : **** Block DemoListenTimeout behavior is started! ****
RX: Listening...
TX: Wait (s): 1.5552562164188521
TX: Send!
RX: Received
TX: Wait (s): 9.200226859896766
RX: Resetting...
RX: Reset!
RX: Listening...
RX: Timeout!
RX: Resetting...
TX: Send! 00:00:10,814
WARN: the signal RandSig has not been consumed and removed from the TimeoutRX@129653c6 pool
TX: Wait (s): 1.4432157474136242
RX: Reset!
RX: Listening...
TX: Send!
TX: Wait (s): 1.3861881386128672
RX: Received
RX: Resetting...
RX: Reset!
RX: Listening...
TX: Send!
RX: Received
TX: Wait (s): 5.207824871218202
RX: Resetting...
RX: Reset!
RX: Listening...
TX: Send!
RX: Received
TX: Wait (s): 8.299783685524481
RX: Resetting...
RX: Reset!
RX: Listening...
RX: Timeout!
TX: Send!
00:00:27,195 WARN: the signal RandSig has not been consumed and removed from the TimeoutRX@129653c6 pool
TX: Wait (s): 7.890720834586661
RX: Resetting...
RX: Reset!
RX: Listening...
TX: Send!
RX: Received
RX: Resetting...
TX: Wait (s): 8.106626568338061
RX: Reset!
RX: Listening...
RX: Timeout!
TX: Send! 00:00:43,206
WARN: the signal RandSig has not been consumed and removed from the TimeoutRX@129653c6 pool
TX: Wait (s): 3.4396829962066455
RX: Resetting...
RX: Reset!
RX: Listening...
TX: Send!
RX: Received
TX: Wait (s): 0.6041322968658347
RX: Resetting...
TX: Send! 00:00:47,270
WARN: the signal RandSig has not been consumed and removed from the TimeoutRX@129653c6 pool
TX: Wait (s): 3.886465876236016
RX: Reset!
RX: Listening...
TX: Send!
RX: Received
RX: Resetting...
TX: Wait (s): 3.3911295830004304
RX: Reset!
RX: Listening...
TX: Send!
RX: Received
RX: Resetting...
TX: Wait (s): 2.1963875013220036
RX: Reset!
RX: Listening...
TX: Send!
RX: Received
TX: Wait (s): 4.20454782376612
RX: Resetting...
RX: Reset!
RX: Listening...
TX: Send!
RX: Received
TX: Wait (s): 8.821911088625512
RX: Resetting...
RX: Reset!
RX: Listening...
RX: Timeout!
TX: Send!
00:01:09,828 WARN: the signal RandSig has not been consumed and removed from the TimeoutRX@129653c6 pool
TX: Wait (s): 0.3336611793717825
RX: Resetting...
TX: Send!
00:01:10,170 WARN: the signal RandSig has not been consumed and removed from the TimeoutRX@129653c6 pool
TX: Wait (s): 3.37676927261699
RX: Reset!
RX: Listening...
TX: Send!
RX: Received
TX: Wait (s): 5.223146007740931 RX: Resetting...
RX: Reset!
RX: Listening...
TX: Send!
RX: Received
TX: Wait (s): 1.8266224580178159
RX: Resetting...
RX: Reset!
RX: Listening... 00:01:20,500 : **** Activity DemoListenTimeout execution is terminated.
**** 00:01:20,501 : **** Block DemoListenTimeout execution is terminated. ****