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
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)