deb-mistral/mistral/workflow/states.py
Winson Chan 433d8e7e99 Fix with-items concurrency for sub-workflows
For with-items task that uses concurrency to execute subworkflows, the
remaining iterations after the first iteration will return the same item
on subworkflow completion. This bug does not affect with-items task that
executes action.

The bug is caused by a delay in the scheduling of workflow execution and
the creation of the execution record. For action execution, the record is
created within the same DB transaction prior to scheduling.

This patch creates the workflow execution record first just like for
action execution and then schedule a resume workflow.

Change-Id: Iba80068260caead9ae8f2f8f105abc5b9349db52
Closes-Bug: #1536415
2016-02-02 17:33:44 +00:00

80 lines
1.8 KiB
Python

# -*- coding: utf-8 -*-
#
# Copyright 2013 - Mirantis, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Valid task and workflow states."""
IDLE = 'IDLE'
WAITING = 'WAITING'
RUNNING = 'RUNNING'
RUNNING_DELAYED = 'DELAYED'
PAUSED = 'PAUSED'
SUCCESS = 'SUCCESS'
ERROR = 'ERROR'
_ALL = [IDLE, WAITING, RUNNING, SUCCESS, ERROR, PAUSED, RUNNING_DELAYED]
_VALID_TRANSITIONS = {
IDLE: [RUNNING, ERROR],
WAITING: [RUNNING],
RUNNING: [PAUSED, RUNNING_DELAYED, SUCCESS, ERROR],
RUNNING_DELAYED: [RUNNING, ERROR],
PAUSED: [RUNNING, ERROR],
SUCCESS: [],
ERROR: [RUNNING]
}
def is_valid(state):
return state in _ALL
def is_invalid(state):
return not is_valid(state)
def is_completed(state):
return state in [SUCCESS, ERROR]
def is_running(state):
return state in [RUNNING, RUNNING_DELAYED]
def is_waiting(state):
return state == WAITING
def is_idle(state):
return state == IDLE
def is_paused(state):
return state == PAUSED
def is_paused_or_completed(state):
return is_paused(state) or is_completed(state)
def is_valid_transition(from_state, to_state):
if is_invalid(from_state) or is_invalid(to_state):
return False
if from_state == to_state:
return True
return to_state in _VALID_TRANSITIONS[from_state]