diff --git a/mistral/db/v2/sqlalchemy/api.py b/mistral/db/v2/sqlalchemy/api.py index a3f7ba85d..0c74e766d 100644 --- a/mistral/db/v2/sqlalchemy/api.py +++ b/mistral/db/v2/sqlalchemy/api.py @@ -21,7 +21,6 @@ from oslo_db import exception as db_exc from oslo_db import sqlalchemy as oslo_sqlalchemy from oslo_db.sqlalchemy import utils as db_utils from oslo_log import log as logging -from oslo_utils import timeutils from oslo_utils import uuidutils import sqlalchemy as sa @@ -96,20 +95,16 @@ def acquire_lock(model, id, session=None): # will be up-to-date from the DB and not from cache. session.expire_all() - if b.get_driver_name() != 'sqlite': - entity = _get_one_entity(model, id) - entity.update({'updated_at': timeutils.utcnow()}) - - else: + if b.get_driver_name() == 'sqlite': + # In case of 'sqlite' we need to apply a manual lock. sqlite_lock.acquire_lock(id, session) - entity = _get_one_entity(model, id) - return entity + return _lock_entity(model, id) -def _get_one_entity(model, id): - # Get entity by ID and expect exactly one object. - return _secure_query(model).filter(model.id == id).one() +def _lock_entity(model, id): + # Get entity by ID in "FOR UPDATE" mode and expect exactly one object. + return _secure_query(model).with_for_update().filter(model.id == id).one() def _secure_query(model, *columns): diff --git a/mistral/workflow/base.py b/mistral/workflow/base.py index d8662f854..21ccecccf 100644 --- a/mistral/workflow/base.py +++ b/mistral/workflow/base.py @@ -70,8 +70,8 @@ class WorkflowController(object): according to this workflow type rules and identifies a list of commands needed to continue the workflow. - :param: task_ex: Task execution to rerun. - :param: reset: If true, then purge action executions for the tasks. + :param task_ex: Task execution to rerun. + :param reset: If true, then purge action executions for the tasks. :param env: A set of environment variables to overwrite. :return: List of workflow commands (instances of mistral.workflow.commands.WorkflowCommand). @@ -88,6 +88,7 @@ class WorkflowController(object): def is_error_handled_for(self, task_ex): """Determines if error is handled for specific task. + :param task_ex: Task execution perform a check for. :return: True if either there is no error at all or error is considered handled. """ diff --git a/tox.ini b/tox.ini index 35a000148..43128bf55 100644 --- a/tox.ini +++ b/tox.ini @@ -39,7 +39,9 @@ commands = oslo-config-generator --config-file tools/config/config-generator.mistral.conf \ --output-file etc/mistral.conf.sample +#set PYTHONHASHSEED=0 to prevent wsmeext.sphinxext from randomly failing. [testenv:venv] +setenv = PYTHONHASHSEED=0 commands = {posargs} #set PYTHONHASHSEED=0 to prevent wsmeext.sphinxext from randomly failing.