Example¶
This scenario was inspired by the teaching problem set out in the paper Describing behaviour of Processes with Many-to-Many Interactions by Dirk Fahland (2019).
Our example concerns the launch by Mission Control of a Space Vehicle. The Vehicle separates from its launcher and orbits the earth.
Mission Control dispatches Recovery Teams to locate both Vehicles after they have separately reentered the atmosphere.
Full source code is here.
DAGs¶
The net of the Vehicle proclet is simple; a linear arrangement of five transitions, terminating at the last.
@property
def dag(self):
return {
self.pro_launch: [self.pro_separation],
self.pro_separation: [self.pro_orbit],
self.pro_orbit: [self.pro_reentry],
self.pro_reentry: [self.pro_recovery],
self.pro_recovery: [],
}
Recovery teams have three transitions, looping continually so that after having finished one job, they are available for another.
@property
def dag(self):
return {
self.pro_tasking: [self.pro_recovery],
self.pro_recovery: [self.pro_standby],
self.pro_standby: [self.pro_tasking],
}
Mission Control is the most complex net. Some transitions loop back to themselves.
@property
def dag(self):
return {
self.pro_launch: [self.pro_separation],
self.pro_separation: [self.pro_reentry],
self.pro_reentry: [self.pro_recovery, self.pro_reentry],
self.pro_recovery: [self.pro_recovery],
}
Transitions¶
In Proclet theory, a Transition is activated when all its input places are occupied by tokens. It can choose whether to fire based on guard conditions. It may also block for a while, in the manner of Timed Petri Nets.
Here we implement each Transition as a single instance method of the Proclet object. It will be useful to adopt a small number of code patterns based on simple Python idiom.
Syncing¶
def pro_launch(self, this, **kwargs):
logging.info("We are go for launch", extra={"proclet": self})
yield from self.channels["uplink"].send(
sender=self.uid, group=self.group,
action=this.__name__,
)
yield
Blocking¶
def pro_launch(self, this, **kwargs):
try:
sync = next(
i for i in self.channels["uplink"].receive(self, this)
if i.action == this.__name__
)
logging.debug(sync, extra={"proclet": self})
except StopIteration:
return
else:
logging.info("Launch phase is complete", extra={"proclet": self})
yield
Forking¶
def pro_separation(self, this, **kwargs):
logging.info("Separation initiated", extra={"proclet": self})
v = Vehicle.create(
name="Launch vehicle", orbits=None,
channels={"beacon": self.channels["beacon"]}, group=self.group,
marking=self.i_nodes[self.pro_reentry],
)
yield v
yield from self.channels["uplink"].send(
sender=self.uid, group=self.group, context={v.uid},
action=this.__name__,
)
yield
Joining¶
@property
def recoveries(self):
return [
msgs[-1] for msgs in self.channels["vhf"].view(self.uid)
if msgs[-1].action == Exit.deliver
]
Finishing¶
def pro_recovery(self, this, **kwargs):
recoveries = {i: r for r in self.recoveries for i in r.context}
if len(recoveries) == 2:
logging.info("Mission complete", extra={"proclet": self})
raise Termination()
Output¶
Mission control| pro_launch|We are go for launch
Space vehicle| pro_launch|Launch phase is complete
Space vehicle|pro_separation|Separation initiated
Mission control|pro_separation|Copy your separation
Launch vehicle| pro_reentry|Re-entering atmosphere
Space vehicle| pro_orbit|In orbit 1
Mission control| pro_reentry|Observing reentry of launch vehicle
Space vehicle| pro_orbit|In orbit 2
Mission control| pro_recovery|Team 81a briefed for recovery of launch vehicle
Space vehicle| pro_orbit|In orbit 3
Recovery Team| pro_recovery|Commencing search for launch vehicle
Recovery Team| pro_recovery|Abandoning search for launch vehicle
Space vehicle| pro_reentry|Re-entering atmosphere
Recovery Team| pro_standby|Team 81a standing by
Mission control| pro_reentry|Observing reentry of space vehicle
Mission control| pro_recovery|Team 81a briefed for recovery of launch vehicle
Recovery Team| pro_recovery|Commencing search for launch vehicle
Recovery Team| pro_recovery|Rendezvous with launch vehicle
Mission control| pro_recovery|Team 1f4 briefed for recovery of space vehicle
Launch vehicle| pro_recovery|Signing off
Recovery Team| pro_standby|Team 81a standing by
Recovery Team| pro_recovery|Commencing search for space vehicle
Recovery Team| pro_recovery|Abandoning search for space vehicle
Mission control| pro_recovery|Team 81a briefed for recovery of space vehicle
Recovery Team| pro_standby|Team 1f4 standing by
Recovery Team| pro_recovery|Commencing search for space vehicle
Recovery Team| pro_recovery|Rendezvous with space vehicle
Mission control| pro_recovery|Mission complete