def template_get_locked_task(project_id, user_id=None, user_ip=None, external_uid=None, limit=1, offset=0, orderby='priority_0', desc=True, rand_within_priority=False, present_gold_task=False, gold_only=False): if offset > 2: raise BadRequest('') if offset > 0: return None task_id, lock_seconds = get_task_id_and_duration_for_project_user( project_id, user_id) if lock_seconds > 10: task = session.query(Task).get(task_id) if task: return [task] user_count = get_active_user_count(project_id, sentinel.master) current_app.logger.info( "Project {} - number of current users: {}".format( project_id, user_count)) sql = query_factory(project_id, user_id=user_id, user_ip=user_ip, external_uid=external_uid, limit=limit, offset=offset, orderby=orderby, desc=desc, rand_within_priority=rand_within_priority, present_gold_task=present_gold_task, gold_only=gold_only) rows = session.execute( sql, dict(project_id=project_id, user_id=user_id, limit=user_count + 5)) for task_id, taskcount, n_answers, calibration, timeout in rows: timeout = timeout or TIMEOUT remaining = float('inf') if calibration else n_answers - taskcount if acquire_lock(task_id, user_id, remaining, timeout): rows.close() save_task_id_project_id(task_id, project_id, 2 * timeout) register_active_user(project_id, user_id, sentinel.master, ttl=timeout) task_type = 'gold task' if calibration else 'task' current_app.logger.info( 'Project {} - user {} obtained {} {}, timeout: {}'.format( project_id, user_id, task_type, task_id, timeout)) return [session.query(Task).get(task_id)] return []
def template_get_locked_task(project_id, user_id=None, user_ip=None, external_uid=None, limit=1, offset=0, orderby='priority_0', desc=True, rand_within_priority=False, task_type='gold_last', filter_user_prefs=False): if offset > 2: raise BadRequest('') if offset > 0: return None task_id, lock_seconds = get_task_id_and_duration_for_project_user(project_id, user_id) if lock_seconds > 10: task = session.query(Task).get(task_id) if task: return [task] user_count = get_active_user_count(project_id, sentinel.master) assign_user = json.dumps({'assign_user': [cached_users.get_user_email(user_id)]}) if user_id else None current_app.logger.info( "Project {} - number of current users: {}" .format(project_id, user_count)) sql = query_factory(project_id, user_id=user_id, limit=limit, rand_within_priority=rand_within_priority, task_type=task_type) limit = current_app.config.get('DB_MAXIMUM_BATCH_SIZE') if filter_user_prefs else user_count + 5 rows = session.execute(sql, dict(project_id=project_id, user_id=user_id, assign_user=assign_user, limit=limit)) user_profile = cached_users.get_user_profile_metadata(user_id) if filter_user_prefs: # validate user qualification and calculate task preference score user_profile = json.loads(user_profile) if user_profile else {} task_rank_info = [] for task_id, taskcount, n_answers, calibration, w_filter, w_pref, timeout in rows: w_pref = w_pref or {} w_filter = w_filter or {} meet_requirement = cached_task_browse_helpers.user_meet_task_requirement(task_id, w_filter, user_profile) if meet_requirement: score = cached_task_browse_helpers.get_task_preference_score(w_pref, user_profile) task_rank_info.append((task_id, taskcount, n_answers, calibration, score, None, timeout)) rows = sorted(task_rank_info, key=lambda tup: tup[4], reverse=True) else: rows = [r for r in rows] for task_id, taskcount, n_answers, calibration, _, _, timeout in rows: timeout = timeout or TIMEOUT remaining = float('inf') if calibration else n_answers - taskcount if acquire_lock(task_id, user_id, remaining, timeout): return _lock_task_for_user(task_id, project_id, user_id, timeout, calibration) return []
def template_get_locked_task(project_id, user_id=None, user_ip=None, external_uid=None, limit=1, offset=0, orderby='priority_0', desc=True): if offset > 2: raise BadRequest() if offset == 1: return None user_count = get_active_user_count(project_id, sentinel.slave) current_app.logger.info( "Project {} - number of current users: {}".format( project_id, user_count)) sql = query_factory(project_id, user_id, user_ip, external_uid, limit, offset, orderby, desc) rows = session.execute( sql, dict(project_id=project_id, user_id=user_id, limit=user_count + 5)) for task_id, taskcount, n_answers, timeout in rows: timeout = timeout or TIMEOUT remaining = n_answers - taskcount if acquire_lock(project_id, task_id, user_id, remaining, timeout): rows.close() register_active_user(project_id, user_id, sentinel.master, ttl=timeout) current_app.logger.info( 'Project {} - user {} obtained task {}, timeout: {}'. format(project_id, user_id, task_id, timeout)) return [session.query(Task).get(task_id)] return []
def template_get_locked_task(project_id, user_id=None, user_ip=None, external_uid=None, limit=1, offset=0, orderby='priority_0', desc=True, rand_within_priority=False, task_type='gold_last', filter_user_prefs=False, task_category_filters=""): if offset > 2: raise BadRequest('') if offset > 0: return None project = project_repo.get(project_id) timeout = project.info.get('timeout', TIMEOUT) task_queue_scheduler = project.info.get( "sched", "default") in [Schedulers.task_queue] reserve_task_config = project.info.get("reserve_tasks", {}).get("category", []) task_id, lock_seconds = get_task_id_and_duration_for_project_user( project_id, user_id) if lock_seconds > 10: task = session.query(Task).get(task_id) if task: return [task] task_id = None user_count = get_active_user_count(project_id, sentinel.master) assign_user = json.dumps({ 'assign_user': [cached_users.get_user_email(user_id)] }) if user_id else None current_app.logger.info( "Project {} - number of current users: {}".format( project_id, user_count)) sql_filters, exclude_user = "", False if task_queue_scheduler and reserve_task_config: sql_filters, category_keys = get_reserve_task_category_info( reserve_task_config, project_id, timeout, user_id) if not category_keys: # no category reserved by current user. search categories # excluding the ones reserved by other users current_app.logger.info( "Project %s, user %s, %s", project_id, user_id, "No task category reserved by user. Search tasks excuding categories reserved by other users" ) exclude_user = True sql_filters, category_keys = get_reserve_task_category_info( reserve_task_config, project_id, timeout, user_id, exclude_user) current_app.logger.info( "SQL filter excuding task categories reserved by other users. sql filter %s", sql_filters) limit = current_app.config.get( 'DB_MAXIMUM_BATCH_SIZE') if filter_user_prefs else user_count + 5 sql = query_factory(project_id, user_id=user_id, limit=limit, rand_within_priority=rand_within_priority, task_type=task_type, task_category_filters=sql_filters) rows = session.execute( sql, dict(project_id=project_id, user_id=user_id, assign_user=assign_user, limit=limit)) if task_queue_scheduler and reserve_task_config and rows and not rows.rowcount and not exclude_user: # With task category reserved by user and no records returned, # no ongoing tasks with task category reserved by user exist. # Hence, query db for tasks excluding task categories reserved # by other users passing exclude_users = True current_app.logger.info( "Project %s, user %s, %s", project_id, user_id, "No task exist with task category already reserved by user. Search tasks excuding categories reserved by other users" ) exclude_user = True release_reserve_task_lock_by_keys(category_keys, timeout) sql_filters, category_keys = get_reserve_task_category_info( reserve_task_config, project_id, timeout, user_id, exclude_user) current_app.logger.info( "SQL filter excuding task categories reserved by other users. sql filter %s", sql_filters) sql = query_factory(project_id, user_id=user_id, limit=limit, rand_within_priority=rand_within_priority, task_type=task_type, task_category_filters=sql_filters) rows = session.execute( sql, dict(project_id=project_id, user_id=user_id, assign_user=assign_user, limit=limit)) user_profile = cached_users.get_user_profile_metadata(user_id) if filter_user_prefs: # validate user qualification and calculate task preference score user_profile = json.loads(user_profile) if user_profile else {} task_rank_info = [] for task_id, taskcount, n_answers, calibration, w_filter, w_pref, timeout in rows: w_pref = w_pref or {} w_filter = w_filter or {} meet_requirement = cached_task_browse_helpers.user_meet_task_requirement( task_id, w_filter, user_profile) if meet_requirement: score = cached_task_browse_helpers.get_task_preference_score( w_pref, user_profile) task_rank_info.append((task_id, taskcount, n_answers, calibration, score, None, timeout)) rows = sorted(task_rank_info, key=lambda tup: tup[4], reverse=True) else: rows = [r for r in rows] for task_id, taskcount, n_answers, calibration, _, _, timeout in rows: timeout = timeout or TIMEOUT remaining = float('inf') if calibration else n_answers - taskcount if acquire_lock(task_id, user_id, remaining, timeout): # reserve tasks acquire_reserve_task_lock(project_id, task_id, user_id, timeout) return _lock_task_for_user(task_id, project_id, user_id, timeout, calibration) return []