Example #1
0
def user_lock_acquire(context, user_id, action_id, engine=None,
                      forced=False):
    """Try to lock the specified user.

    :param context: the context used for DB operations;
    :param user_id: ID of the user to be locked.
    :param action_id: ID of the action that attempts to lock the user.
    :param engine: ID of the engine that attempts to lock the user.
    :param forced: set to True to cancel current action that owns the lock,
                   if any.
    :returns: True if lock is acquired, or False otherwise.
    """

    owner = db_api.user_lock_acquire(user_id, action_id)
    if action_id == owner:
        return True

    retries = cfg.CONF.lock_retry_times
    retry_interval = cfg.CONF.lock_retry_interval

    while retries > 0:
        sleep(retry_interval)
        LOG.debug(_('Acquire lock for user %s again'), user_id)
        owner = db_api.user_lock_acquire(user_id, action_id)
        if action_id == owner:
            return True
        retries = retries - 1

    if forced:
        owner = db_api.user_lock_steal(user_id, action_id)
        return action_id == owner

    action = db_api.action_get(context, owner)
    if (action and action.owner and action.owner != engine and
            is_engine_dead(context, action.owner)):
        LOG.info(_LI('The user %(u)s is locked by dead action %(a)s, '
                     'try to steal the lock.'), {
            'u': user_id,
            'a': owner
        })
        reason = _('Engine died when executing this action.')
        db_api.action_mark_failed(context, action.id, time.time(),
                                  reason=reason)
        db_api.user_lock_steal(user_id, action_id)
        return True

    LOG.error(_LE('User is already locked by action %(old)s, '
                  'action %(new)s failed grabbing the lock'),
              {'old': owner, 'new': action_id})

    return False
Example #2
0
    def load(cls, context, action_id=None, db_action=None):
        """Retrieve an action from database.

        :param context: Instance of request context.
        :param action_id: An UUID for the action to deserialize.
        :param db_action: An action object for the action to deserialize.
        :return: A `Action` object instance.
        """
        if db_action is None:
            db_action = db_api.action_get(context, action_id)
            if db_action is None:
                raise exception.ActionNotFound(action=action_id)

        return cls._from_db_record(db_action)