예제 #1
0
def clks_uploaded_to_project(project_id, check_data_ready=False):
    """ See if the given project has had all parties contribute data.
    """
    logger.info("Counting contributing parties")
    conn = connect_db()
    if check_data_ready:
        parties_contributed = get_number_parties_ready(conn, project_id)
        logger.info("Parties where data is ready: {}".format(parties_contributed))
    else:
        parties_contributed = get_number_parties_uploaded(conn, project_id)
        logger.info("Parties where data is uploaded: {}".format(parties_contributed))
    number_parties = get_project_column(conn, project_id, 'parties')
    logger.info("{}/{} parties have contributed clks".format(parties_contributed, number_parties))
    return parties_contributed == number_parties
예제 #2
0
def post(project_id, run):
    log = logger.bind(pid=project_id)
    log.debug("Processing request to add a new run", run=run)
    # Check the resource exists
    abort_if_project_doesnt_exist(project_id)

    # Check the caller has a valid results token. Yes it should be renamed.
    abort_if_invalid_results_token(project_id,
                                   request.headers.get('Authorization'))

    abort_if_project_in_error_state(project_id)

    run_model = Run.from_json(run, project_id)

    log.debug("Saving run")

    with db.DBConn() as db_conn:
        run_model.save(db_conn)
        project_object = db.get_project(db_conn, project_id)
        parties_contributed = db.get_number_parties_uploaded(
            db_conn, project_id)
        ready_to_run = parties_contributed == project_object['parties']
        log.debug(
            "Expecting {} parties to upload data. Have received {}".format(
                project_object['parties'], parties_contributed))
        if ready_to_run:
            log.info(
                "Scheduling task to carry out all runs for project {} now".
                format(project_id))
            update_run_mark_queued(db_conn, run_model.run_id)
        else:
            log.info("Task queued but won't start until CLKs are all uploaded")

    if ready_to_run:
        span = g.flask_tracer.get_span()
        span.set_tag("run_id", run_model.run_id)
        span.set_tag("project_id", run_model.project_id)
        check_for_executable_runs.delay(project_id, serialize_span(span))
    return RunDescription().dump(run_model), 201
예제 #3
0
def project_get(project_id):
    """
    This endpoint describes a Project.
    """
    log = logger.bind(pid=project_id)
    log.info("Getting detail for a project")
    abort_if_project_doesnt_exist(project_id)
    authorise_get_request(project_id)
    with DBConn() as db_conn:
        project_object = db.get_project(db_conn, project_id)
        # Expose the number of data providers who have uploaded clks
        parties_contributed = db.get_number_parties_uploaded(
            db_conn, project_id)
        num_parties_with_error = db.get_encoding_error_count(
            db_conn, project_id)
    log.info(f"{parties_contributed} parties have contributed hashes")
    project_object['parties_contributed'] = parties_contributed

    if num_parties_with_error > 0:
        log.warning(
            f"There are {num_parties_with_error} parties in error state")
    project_object['error'] = num_parties_with_error > 0

    return ProjectDescription().dump(project_object)
예제 #4
0
def get(project_id, run_id):
    log = logger.bind(pid=project_id, rid=run_id)
    parent_span = g.flask_tracer.get_span()
    log.debug("request run status")
    with opentracing.tracer.start_span('check-auth',
                                       child_of=parent_span) as span:
        # Check the project and run resources exist
        abort_if_run_doesnt_exist(project_id, run_id)

        # Check the caller has a valid results token. Yes it should be renamed.
        auth_token_type = get_authorization_token_type_or_abort(
            project_id, request.headers.get('Authorization'))
        log.debug(
            "Run status authorized using {} token".format(auth_token_type))

    with opentracing.tracer.start_span('get-status-from-db',
                                       child_of=parent_span) as span:
        dbinstance = get_db()
        run_status = db.get_run_status(dbinstance, run_id)
        project_in_error = db.get_encoding_error_count(dbinstance,
                                                       project_id) > 0
        span.set_tag('stage', run_status['stage'])

    run_type = RUN_TYPES[run_status['type']]
    state = 'error' if project_in_error else run_status['state']
    stage = run_status['stage']
    status = {
        "state": state,
        "time_added": run_status['time_added'],
        "stages": run_type['stages'],
        "current_stage": {
            "number":
            stage,
            "description":
            run_type['stage_descriptions'].get(
                stage, "there is no description for this stage")
        }
    }
    # trying to get progress if available
    if stage == 1:
        # waiting for CLKs
        abs_val = db.get_number_parties_uploaded(dbinstance, project_id)
        max_val = db.get_project_column(dbinstance, project_id, 'parties')
    elif stage == 2:
        # Computing similarity
        abs_val = cache.get_progress(run_id)
        if abs_val is not None:
            max_val = db.get_total_comparisons_for_project(
                dbinstance, project_id)
    else:
        # Solving for mapping (no progress)
        abs_val = None
    if abs_val is not None:
        progress = {
            'absolute': abs_val,
            'relative': (abs_val / max_val) if max_val != 0 else 0,
        }
        if progress['relative'] > 1.0:
            log.warning('oh no. more than 100% ??? abs: {}, max: {}'.format(
                abs_val, max_val))
        if run_status['stage'] in run_type['stage_progress_descriptions']:
            progress['description'] = run_type['stage_progress_descriptions'][
                run_status['stage']]
        status["current_stage"]["progress"] = progress
    if state == 'completed':
        status["time_started"] = run_status['time_started']
        status["time_completed"] = run_status['time_completed']
        return completed().dump(status)
    elif state == 'running' or state == 'queued' or state == 'created':
        status["time_started"] = run_status['time_started']
        return running().dump(status)
    elif state == 'error':
        log.warning(
            'handling the run status for state "error" is not implemented')
        return error().dump(status)