def acquire_reserve_task_lock(project_id, task_id, user_id, timeout, pipeline=None, execute=True): task = task_repo.get_task(task_id) project = project_repo.get(project_id) if not (task and project and project.info.get("sched", "default") in [Schedulers.task_queue]): return False reserve_task_config = project.info.get("reserve_tasks", {}).get("category", []) category_exist = reserve_task_config and all( task.info.get(field, False) for field in reserve_task_config) if not category_exist: return False category = [ "{}:{}".format(field, task.info.get(field)) for field in reserve_task_config ] category = ":".join(category) redis_conn = sentinel.master pipeline = pipeline or redis_conn.pipeline(transaction=True) lock_manager = LockManager(redis_conn, timeout) if lock_manager.acquire_reserve_task_lock(project_id, task_id, user_id, category): current_app.logger.info( "Acquired reserve task lock. project %s, task %s, user %s, category %s", project_id, task_id, user_id, category) return True return False
def get_reserve_task_category_info(reserve_task_config, project_id, timeout, user_id, exclude_user=False): """Get reserved category info for a given user under a given project""" sql_filters, category_keys = "", [] if not reserve_task_config: return sql_filters, category_keys category = ":".join( ["{}:*".format(field) for field in sorted(reserve_task_config)]) lock_manager = LockManager(sentinel.master, timeout) category_keys = lock_manager.get_task_category_lock( project_id, user_id, category, exclude_user) current_app.logger.info( "Project %s, user %s, reserve config %s, exclude %s. reserve task category keys %s", project_id, user_id, json.dumps(reserve_task_config), exclude_user, str(category_keys)) if not category_keys: return sql_filters, category_keys sql_filters, category_keys = reserve_task_sql_filters( project_id, category_keys, exclude_user) return sql_filters, category_keys
def release_lock(task_id, user_id, timeout, pipeline=None, execute=True): redis_conn = sentinel.master pipeline = pipeline or redis_conn.pipeline(transaction=True) lock_manager = LockManager(redis_conn, timeout) task_users_key = get_task_users_key(task_id) user_tasks_key = get_user_tasks_key(user_id) lock_manager.release_lock(task_users_key, user_id, pipeline=pipeline) lock_manager.release_lock(user_tasks_key, task_id, pipeline=pipeline) if execute: pipeline.execute()
def acquire_lock(task_id, user_id, limit, timeout, pipeline=None, execute=True): redis_conn = sentinel.master pipeline = pipeline or redis_conn.pipeline(transaction=True) lock_manager = LockManager(redis_conn, timeout) task_users_key = get_task_users_key(task_id) user_tasks_key = get_user_tasks_key(user_id) if lock_manager.acquire_lock(task_users_key, user_id, limit, pipeline=pipeline): lock_manager.acquire_lock(user_tasks_key, task_id, float('inf'), pipeline=pipeline) if execute: return all(not isinstance(r, Exception) for r in pipeline.execute()) return True return False
def release_lock(task_id, user_id, timeout, pipeline=None, execute=True): redis_conn = sentinel.master pipeline = pipeline or redis_conn.pipeline(transaction=True) lock_manager = LockManager(redis_conn, timeout) task_users_key = get_task_users_key(task_id) user_tasks_key = get_user_tasks_key(user_id) lock_manager.release_lock(task_users_key, user_id, pipeline=pipeline) lock_manager.release_lock(user_tasks_key, task_id, pipeline=pipeline) project_ids = get_task_ids_project_id([task_id]) if project_ids: unregister_active_user(project_ids[0], user_id, sentinel.master) if execute: pipeline.execute()
def release_reserve_task_lock_by_keys(resource_ids, timeout, pipeline=None, expiry=EXPIRE_RESERVE_TASK_LOCK_DELAY): if not resource_ids: return redis_conn = sentinel.master pipeline = redis_conn.pipeline(transaction=True) lock_manager = LockManager(redis_conn, timeout) for resource_id in resource_ids: lock_manager.release_reserve_task_lock(resource_id, pipeline, expiry) current_app.logger.info( "Release reserve task lock. resource id %s, expiry %d", resource_id, expiry)
def get_locked_tasks_project(project_id): """Returns a list of locked tasks for a given project.""" tasks = [] redis_conn = sentinel.master # Get the active users key for this project. key = get_active_user_key(project_id) # Get the users for each locked task. for user_key in redis_conn.hgetall(key).iteritems(): user_id = user_key[0] # Get locks by user. user_tasks = get_user_tasks(user_id, TIMEOUT) # Get task ids for the locks. user_task_ids = user_tasks.keys() # Get project ids for the task ids. results = get_task_ids_project_id(user_task_ids) # For each locked task, check if the lock is still active. for task_id, task_project_id in zip(user_task_ids, results): # Match the requested project id. if int(task_project_id) == project_id: # Calculate seconds remaining. seconds_remaining = LockManager.seconds_remaining(user_tasks[task_id]) if seconds_remaining > 0: # This lock has not yet expired. tasks.append({ "user_id": user_id, "task_id": task_id, "seconds_remaining": seconds_remaining }) return tasks
def release_reserve_task_lock_by_id(project_id, task_id, user_id, timeout, expiry=EXPIRE_RESERVE_TASK_LOCK_DELAY): reserve_key = get_reserve_task_key(task_id) if not reserve_key: return redis_conn = sentinel.master pipeline = redis_conn.pipeline(transaction=True) lock_manager = LockManager(redis_conn, timeout) resource_id = "reserve_task:project:{}:category:{}:user:{}:task:{}".format( project_id, reserve_key, user_id, task_id) lock_manager.release_reserve_task_lock(resource_id, pipeline, expiry) current_app.logger.info( "Release reserve task lock. project %s, task %s, user %s, expiry %d", project_id, task_id, user_id, expiry)
def get_task_id_and_duration_for_project_user(project_id, user_id): user_tasks = get_user_tasks(user_id, TIMEOUT) user_task_ids = user_tasks.keys() results = get_task_ids_project_id(user_task_ids) max_seconds_task_id = -1 max_seconds_remaining = float('-inf') for task_id, task_project_id in zip(user_task_ids, results): if not task_project_id: task_project_id = task_repo.get_task(task_id).project_id save_task_id_project_id(task_id, task_project_id, 2 * TIMEOUT) if int(task_project_id) == project_id: seconds_remaining = LockManager.seconds_remaining( user_tasks[task_id]) if seconds_remaining > max_seconds_remaining: max_seconds_task_id = int(task_id) max_seconds_remaining = seconds_remaining if max_seconds_task_id > 0: return max_seconds_task_id, max_seconds_remaining return None, -1
def get_user_tasks(user_id, timeout): lock_manager = LockManager(sentinel.master, timeout) user_tasks_key = get_user_tasks_key(user_id) return lock_manager.get_locks(user_tasks_key)
def get_locks(task_id, timeout): lock_manager = LockManager(sentinel.master, timeout) task_users_key = get_task_users_key(task_id) return lock_manager.get_locks(task_users_key)
def has_lock(task_id, user_id, timeout): lock_manager = LockManager(sentinel.master, timeout) task_users_key = get_task_users_key(task_id) return lock_manager.has_lock(task_users_key, user_id)
def release_lock(project_id, task_id, user_id, timeout): lock_manager = LockManager(sentinel.master, timeout) key = get_key(project_id, task_id) lock_manager.release_lock(key, user_id)
def acquire_lock(project_id, task_id, user_id, limit, timeout): lock_manager = LockManager(sentinel.master, timeout) key = get_key(project_id, task_id) return lock_manager.acquire_lock(key, user_id, limit)
def has_lock(project_id, task_id, user_id, timeout): lock_manager = LockManager(sentinel.master, timeout) key = get_key(project_id, task_id) return lock_manager.has_lock(key, user_id)