...
 
Commits (2)
......@@ -4,14 +4,22 @@
# 1. The action-state diagram for the design document
# 2. Go code for the core state machine in the policy daemon.
import sys
class dot:
"Output class for rendering to state diagram."
def __init__(self):
self.nstates = 0
self.nactions = 0
def begin(self):
print('strict digraph {\n size="10,20";')
def end(self):
print('}')
sys.stderr.write("%d states, %d events, %d transitions.\n" \
% (self.nstates, len(events)-1, self.nactions))
def state(self, node, text):
print(' "{0}" [shape=oval, label="{1}"]'.format(node, text))
self.nstates += 1
def action(self, fromstate, tostate, production, unreachable=False):
label = "Trigger: %s\nMeans: %s" \
% (events[production.trigger], production.meaning)
......@@ -23,6 +31,7 @@ class dot:
if unreachable:
arc = ' edge [style=dotted]\n' + arc + '\n edge [style=solid]'
print(arc)
self.nactions += 1
class flowgraph:
def __init__(self):
......@@ -144,6 +153,10 @@ class production:
self.hook = hook
def alarmname(self):
return "Alarm" + self.alarm.capitalize()
#
# Actual policy specification starts here. Stuff before this point was
# generic machinery to compile the specification into output products.
#
# Triggers.
events = {
......@@ -198,8 +211,7 @@ HOSTDOWN = production("HostShutsDown",
trigger="EventHostOff",
meaning="Host has shut down")
RESTORED_LATE = production("RestoredLate",
trigger="EventGoodAC",
meaning="Power came back after host shut down",
trigger="EventGoodAC", meaning="Power came back after host shut down",
alarm="UP",
action="Action: Cycle AC power to load host.",
hook="CycleHostPower()")
......@@ -212,6 +224,10 @@ if __name__ == '__main__':
render = go_daemon()
# This is the pseudocode describing state-action transitions.
#
# Actions marked "unreachable" are for the state-transition
# diagram only, the code can never get there because they're
# contingent on power cutting out while mains is unvailable..
render.begin()
render.state("DaemonUp", "Daemon running")
render.action("DaemonUp", "ChargeWait", CHARGING)
......