Ejemplo n.º 1
0
    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 []
Ejemplo n.º 2
0
    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 []
Ejemplo n.º 3
0
    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 []
Ejemplo n.º 4
0
    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 []