예제 #1
0
def stop_matched_holdingpen_wfs(obj, eng):
    """Stop the matched workflow objects in the holdingpen.

    Stops the matched workflows in the holdingpen by replacing their steps with
    a new one defined on the fly, containing a ``stop`` step, and executing it.
    For traceability reason, these workflows are also marked as
    ``'stopped-by-wf'``, whose value is the current workflow's id.

    In the use case of harvesting twice an article, this function is involved
    to stop the first workflow and let the current one being processed,
    since it the latest metadata.

    Args:
        obj: a workflow object.
        eng: a workflow engine.

    Returns:
        None
    """
    stopping_steps = [mark('stopped-by-wf', int(obj.id)), stop_processing]

    save_workflow(obj, eng)

    for holdingpen_wf_id in obj.extra_data['holdingpen_matches']:
        holdingpen_wf = workflow_object_class.get(holdingpen_wf_id)
        holdingpen_wf_eng = WorkflowEngine.from_uuid(holdingpen_wf.id_workflow)

        # stop this holdingpen workflow by replacing its steps with a stop step
        holdingpen_wf_eng.callbacks.replace(stopping_steps)
        holdingpen_wf_eng.process([holdingpen_wf])
예제 #2
0
def stop_matched_holdingpen_wfs(obj, eng):
    """Stop the matched workflow objects in the holdingpen.

    Stops the matched workflows in the holdingpen by replacing their steps with
    a new one defined on the fly, containing a ``stop`` step, and executing it.
    For traceability reason, these workflows are also marked as
    ``'stopped-by-wf'``, whose value is the current workflow's id.

    In the use case of harvesting twice an article, this function is involved
    to stop the first workflow and let the current one being processed,
    since it the latest metadata.

    Args:
        obj: a workflow object.
        eng: a workflow engine.

    Returns:
        None
    """
    stopping_steps = [mark('stopped-by-wf', int(obj.id)), stop_processing]

    save_workflow(obj, eng)

    for holdingpen_wf_id in obj.extra_data['holdingpen_matches']:
        holdingpen_wf = workflow_object_class.get(holdingpen_wf_id)
        holdingpen_wf_eng = WorkflowEngine.from_uuid(holdingpen_wf.id_workflow)

        # stop this holdingpen workflow by replacing its steps with a stop step
        holdingpen_wf_eng.callbacks.replace(stopping_steps)
        holdingpen_wf_eng.process([holdingpen_wf])
예제 #3
0
def run_next_if_necessary(obj, eng):
    """Remove current wf id from matched workflows and run next one"""
    blocked_wfs = set_wf_not_completed_ids_to_wf(obj, skip_blocked=False)
    next_wf = None
    for wf_id in blocked_wfs:
        wf = workflow_object_class.get(wf_id)
        if obj.id in wf.extra_data.get('holdingpen_matches', []):
            wf.extra_data['holdingpen_matches'].remove(obj.id)
            save_workflow(wf, eng)
        if not wf.extra_data.get('holdingpen_matches', []) and not next_wf:
            # If workflow is not blocked by any other workflow
            # And there is no next workflow set
            # then set is as next to restart
            next_wf = wf
    if next_wf:
        restart_workflow(next_wf, obj.id)
예제 #4
0
def run_next_if_necessary(obj, eng):
    """Remove current wf id from matched workflows and run next one"""
    blocked_wfs = set_wf_not_completed_ids_to_wf(obj, skip_blocked=False)
    next_wf = None
    for wf_id in blocked_wfs:
        wf = workflow_object_class.get(wf_id)
        if obj.id in wf.extra_data.get('holdingpen_matches', []):
            wf.extra_data['holdingpen_matches'].remove(obj.id)
            save_workflow(wf, eng)
        if not wf.extra_data.get('holdingpen_matches', []) and not next_wf:
            # If workflow is not blocked by any other workflow
            # And there is no next workflow set
            # then set is as next to restart
            next_wf = wf
    if next_wf:
        restart_workflow(next_wf, obj.id)
예제 #5
0
def set_wf_not_completed_ids_to_wf(obj, skip_blocked=True, skip_halted=False):
    """Return list of all matched workflows ids which are not completed
    also stores this list to wf.extra_data['holdingpen_matches']
    By default it do not show workflows which are already blocked by this workflow

    Arguments:
        obj: a workflow object.
        skip_blocked: boolean, if True do not returnd workflows blocked by this one,
            if False then return all matched workflows.
        skip_halted: boolean, if True, then it skips HALTED workflows when
            looking for matched workflows
    """
    def _non_completed(base_record, match_result):
        return get_value(match_result,
                         '_source._workflow.status') != 'COMPLETED'

    def _not_completed_or_halted(base_record, match_result):
        return get_value(match_result, '_source._workflow.status') not in [
            'COMPLETED', 'HALTED'
        ]

    def is_workflow_blocked_by_another_workflow(workflow_id):
        workflow = workflow_object_class.get(workflow_id)
        return obj.id in workflow.extra_data.get('holdingpen_matches', [])

    if skip_halted:
        matched_ids = pending_in_holding_pen(obj, _not_completed_or_halted)
    else:
        matched_ids = pending_in_holding_pen(obj, _non_completed)

    if skip_blocked:
        matched_ids = [
            _id for _id in matched_ids
            if not is_workflow_blocked_by_another_workflow(_id)
        ]
    obj.extra_data['holdingpen_matches'] = matched_ids
    save_workflow(obj, None)
    return matched_ids
예제 #6
0
def set_wf_not_completed_ids_to_wf(obj, skip_blocked=True, skip_halted=False):
    """Return list of all matched workflows ids which are not completed
    also stores this list to wf.extra_data['holdingpen_matches']
    By default it do not show workflows which are already blocked by this workflow

    Arguments:
        obj: a workflow object.
        skip_blocked: boolean, if True do not returnd workflows blocked by this one,
            if False then return all matched workflows.
        skip_halted: boolean, if True, then it skips HALTED workflows when
            looking for matched workflows
    """

    def _non_completed(base_record, match_result):
        return get_value(match_result,
                         '_source._workflow.status') != 'COMPLETED'

    def _not_completed_or_halted(base_record, match_result):
        return get_value(match_result, '_source._workflow.status') not in [
            'COMPLETED', 'HALTED']

    def is_workflow_blocked_by_another_workflow(workflow_id):
        workflow = workflow_object_class.get(workflow_id)
        return obj.id in workflow.extra_data.get('holdingpen_matches', [])

    if skip_halted:
        matched_ids = pending_in_holding_pen(obj, _not_completed_or_halted)
    else:
        matched_ids = pending_in_holding_pen(obj, _non_completed)

    if skip_blocked:
        matched_ids = [_id for _id in matched_ids if
                       not is_workflow_blocked_by_another_workflow(_id)]
    obj.extra_data['holdingpen_matches'] = matched_ids
    save_workflow(obj, None)
    return matched_ids