diff --git a/doc/source/img/job_states.svg b/doc/source/img/job_states.svg
new file mode 100644
index 000000000..17fd4e712
--- /dev/null
+++ b/doc/source/img/job_states.svg
@@ -0,0 +1,8 @@
+
+
+
+
+
diff --git a/doc/source/states.rst b/doc/source/states.rst
index 9cc7a50a9..360354804 100644
--- a/doc/source/states.rst
+++ b/doc/source/states.rst
@@ -194,3 +194,26 @@ already in the ``FAILURE`` state then this is a no-op).
**RETRYING** - If flow that is associated with the current retry was failed and
reverted, the engine prepares the flow for the next run and transitions the
retry to the ``RETRYING`` state.
+
+Jobs
+====
+
+.. image:: img/job_states.svg
+ :width: 500px
+ :align: center
+ :alt: Job state transitions
+
+**UNCLAIMED** - A job (with details about what work is to be completed) has
+been initially posted (by some posting entity) for work on by some other
+entity (for example a :doc:`conductor `). This can also be a state
+that is entered when some owning entity has manually abandoned (or
+lost ownership of) a previously claimed job.
+
+**CLAIMED** - A job that is *actively* owned by some entity; typically that
+ownership is tied to jobs persistent data via some ephemeral connection so
+that the job ownership is lost (typically automatically or after some
+timeout) if that ephemeral connection is lost.
+
+**COMPLETE** - The work defined in the job has been finished by its owning
+entity and the job can no longer be processed (and it *may* be removed at
+some/any point in the future).
diff --git a/taskflow/states.py b/taskflow/states.py
index 28272cd3a..85cda2d0a 100644
--- a/taskflow/states.py
+++ b/taskflow/states.py
@@ -53,6 +53,21 @@ SCHEDULING = 'SCHEDULING'
WAITING = 'WAITING'
ANALYZING = 'ANALYZING'
+# Job state transitions
+# See: http://docs.openstack.org/developer/taskflow/states.html
+
+_ALLOWED_JOB_TRANSITIONS = frozenset((
+ # Job is being claimed.
+ (UNCLAIMED, CLAIMED),
+
+ # Job has been lost (or manually unclaimed/abandoned).
+ (CLAIMED, UNCLAIMED),
+
+ # Job has been finished.
+ (CLAIMED, COMPLETE),
+))
+
+
# Flow state transitions
# See: http://docs.openstack.org/developer/taskflow/states.html
diff --git a/tools/generate_states.sh b/tools/generate_states.sh
index 308c64000..60ca3d4b9 100755
--- a/tools/generate_states.sh
+++ b/tools/generate_states.sh
@@ -34,3 +34,7 @@ $xsltproc $PWD/.diagram-tools/notugly.xsl /tmp/states.svg > $img_dir/retry_state
echo "---- Updating wbe request state diagram ----"
python $script_dir/state_graph.py -w -f /tmp/states.svg
$xsltproc $PWD/.diagram-tools/notugly.xsl /tmp/states.svg > $img_dir/wbe_request_states.svg
+
+echo "---- Updating job state diagram ----"
+python $script_dir/state_graph.py -j -f /tmp/states.svg
+$xsltproc $PWD/.diagram-tools/notugly.xsl /tmp/states.svg > $img_dir/job_states.svg
diff --git a/tools/state_graph.py b/tools/state_graph.py
index 5ba9da7fb..7711826eb 100755
--- a/tools/state_graph.py
+++ b/tools/state_graph.py
@@ -71,7 +71,7 @@ def map_color(internal_states, state):
return 'red'
if state == states.REVERTED:
return 'darkorange'
- if state == states.SUCCESS:
+ if state in (states.SUCCESS, states.COMPLETE):
return 'green'
return None
@@ -96,6 +96,10 @@ def main():
action='store_true',
help="use wbe request transitions",
default=False)
+ parser.add_option("-j", "--jobs", dest="jobs",
+ action='store_true',
+ help="use job transitions",
+ default=False)
parser.add_option("-T", "--format", dest="format",
help="output in given format",
default='svg')
@@ -109,9 +113,10 @@ def main():
options.retries,
options.tasks,
options.wbe_requests,
+ options.jobs,
]
if sum([int(i) for i in types]) > 1:
- parser.error("Only one of task/retry/engines/wbe requests"
+ parser.error("Only one of task/retry/engines/wbe requests/jobs"
" may be specified.")
internal_states = list()
@@ -135,6 +140,10 @@ def main():
source_type = "WBE requests"
source = make_machine(protocol.WAITING,
list(protocol._ALLOWED_TRANSITIONS), [])
+ elif options.jobs:
+ source_type = "Jobs"
+ source = make_machine(states.UNCLAIMED,
+ list(states._ALLOWED_JOB_TRANSITIONS), [])
else:
source_type = "Flow"
source = make_machine(states.PENDING,