e54cb21d55
Switch to using the `state_graph.py` and dot output as the source of all of the state diagrams (this makes it easy for anyone to recreate them by just running the script in the tools directory). Also update the state diagram creator to have engine states as well as retry states and replaces all existing state diagrams with the updated prettified versions. Also adjusts some nits around wording and grammar that were encountered during this updating process. Change-Id: Ia783aed6c4136763e1e34cbd0b3e57ffb1109abe
131 lines
4.5 KiB
Python
Executable File
131 lines
4.5 KiB
Python
Executable File
#!/usr/bin/env python
|
|
|
|
import optparse
|
|
import os
|
|
import sys
|
|
|
|
top_dir = os.path.abspath(os.path.join(os.path.dirname(__file__),
|
|
os.pardir))
|
|
sys.path.insert(0, top_dir)
|
|
|
|
import networkx as nx
|
|
|
|
# To get this installed you may have to follow:
|
|
# https://code.google.com/p/pydot/issues/detail?id=93 (until fixed).
|
|
import pydot
|
|
|
|
from taskflow import states
|
|
|
|
|
|
def main():
|
|
parser = optparse.OptionParser()
|
|
parser.add_option("-f", "--file", dest="filename",
|
|
help="write svg to FILE", metavar="FILE")
|
|
parser.add_option("-t", "--tasks", dest="tasks",
|
|
action='store_true',
|
|
help="use task state transitions",
|
|
default=False)
|
|
parser.add_option("-r", "--retries", dest="retries",
|
|
action='store_true',
|
|
help="use retry state transitions",
|
|
default=False)
|
|
parser.add_option("-e", "--engines", dest="engines",
|
|
action='store_true',
|
|
help="use engine state transitions",
|
|
default=False)
|
|
parser.add_option("-T", "--format", dest="format",
|
|
help="output in given format",
|
|
default='svg')
|
|
|
|
(options, args) = parser.parse_args()
|
|
if options.filename is None:
|
|
options.filename = 'states.%s' % options.format
|
|
|
|
types = [options.engines, options.retries, options.tasks]
|
|
if sum([int(i) for i in types]) > 1:
|
|
parser.error("Only one of task/retry/engines may be specified.")
|
|
|
|
disallowed = set()
|
|
start_node = states.PENDING
|
|
if options.tasks:
|
|
source = list(states._ALLOWED_TASK_TRANSITIONS)
|
|
source_type = "Tasks"
|
|
disallowed.add(states.RETRYING)
|
|
elif options.retries:
|
|
source = list(states._ALLOWED_TASK_TRANSITIONS)
|
|
source_type = "Retries"
|
|
elif options.engines:
|
|
# TODO(harlowja): place this in states.py
|
|
source = [
|
|
(states.RESUMING, states.SCHEDULING),
|
|
(states.SCHEDULING, states.WAITING),
|
|
(states.WAITING, states.ANALYZING),
|
|
(states.ANALYZING, states.SCHEDULING),
|
|
(states.ANALYZING, states.WAITING),
|
|
]
|
|
for u in (states.SCHEDULING, states.ANALYZING):
|
|
for v in (states.SUSPENDED, states.SUCCESS, states.REVERTED):
|
|
source.append((u, v))
|
|
source_type = "Engines"
|
|
start_node = states.RESUMING
|
|
else:
|
|
source = list(states._ALLOWED_FLOW_TRANSITIONS)
|
|
source_type = "Flow"
|
|
|
|
transitions = nx.DiGraph()
|
|
for (u, v) in source:
|
|
if u not in disallowed:
|
|
transitions.add_node(u)
|
|
if v not in disallowed:
|
|
transitions.add_node(v)
|
|
for (u, v) in source:
|
|
if not transitions.has_node(u) or not transitions.has_node(v):
|
|
continue
|
|
transitions.add_edge(u, v)
|
|
|
|
graph_name = "%s states" % source_type
|
|
g = pydot.Dot(graph_name=graph_name, rankdir='LR',
|
|
nodesep='0.25', overlap='false',
|
|
ranksep="0.5", size="11x8.5",
|
|
splines='true', ordering='in')
|
|
node_attrs = {
|
|
'fontsize': '11',
|
|
}
|
|
nodes = {}
|
|
nodes_order = []
|
|
edges_added = []
|
|
for (u, v) in nx.bfs_edges(transitions, source=start_node):
|
|
if u not in nodes:
|
|
nodes[u] = pydot.Node(u, **node_attrs)
|
|
g.add_node(nodes[u])
|
|
nodes_order.append(u)
|
|
if v not in nodes:
|
|
nodes[v] = pydot.Node(v, **node_attrs)
|
|
g.add_node(nodes[v])
|
|
nodes_order.append(v)
|
|
for u in nodes_order:
|
|
for v in transitions.successors_iter(u):
|
|
if (u, v) not in edges_added:
|
|
g.add_edge(pydot.Edge(nodes[u], nodes[v]))
|
|
edges_added.append((u, v))
|
|
start = pydot.Node("__start__", shape="point", width="0.1",
|
|
xlabel='start', fontcolor='green', **node_attrs)
|
|
g.add_node(start)
|
|
g.add_edge(pydot.Edge(start, nodes[start_node], style='dotted'))
|
|
|
|
print("*" * len(graph_name))
|
|
print(graph_name)
|
|
print("*" * len(graph_name))
|
|
print(g.to_string().strip())
|
|
|
|
g.write(options.filename, format=options.format)
|
|
print("Created %s at '%s'" % (options.format, options.filename))
|
|
|
|
# To make the svg more pretty use the following:
|
|
# $ xsltproc ../diagram-tools/notugly.xsl ./states.svg > pretty-states.svg
|
|
# Get diagram-tools from https://github.com/vidarh/diagram-tools.git
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|