Process the notification.

def worker_function(event_type, assignment_id, participant_id):
    """Process the notification."""
    db.logger.debug("rq: worker_function working on job id: %s",
                    get_current_job().id)
    db.logger.debug('rq: Received Queue Length: %d (%s)', len(q),
                    ', '.join(q.job_ids))

    exp = experiment(session)
    key = "-----"

    exp.log("Received an {} notification for assignment {}, participant {}"
            .format(event_type, assignment_id, participant_id), key)

    if assignment_id is not None:
        # save the notification to the notification table
        notif = models.Notification(
            assignment_id=assignment_id,
            event_type=event_type)
        session.add(notif)
        session.commit()

        # try to identify the participant
        participants = models.Participant.query\
            .filter_by(assignment_id=assignment_id)\
            .all()

        # if there are multiple participants select the most recent
        if len(participants) > 1:
            if event_type in ['AssignmentAbandoned', 'AssignmentReturned']:
                participants = [p for p in participants if
                                p.status == "working"]
                if participants:
                    participant = min(participants,
                                      key=attrgetter('creation_time'))
                else:
                    return None
            else:
                participant = max(participants,
                                  key=attrgetter('creation_time'))

        # if there are none (this is also bad news) print an error
        elif len(participants) == 0:
            exp.log("Warning: No participants associated with this "
                    "assignment_id. Notification will not be processed.", key)
            return None

        # if theres only one participant (this is good) select them
        else:
            participant = participants[0]

    elif participant_id is not None:
        participant = models.Participant.query\
            .filter_by(id=participant_id).all()[0]
    else:
        raise ValueError(
            "Error: worker_function needs either an assignment_id or a "
            "participant_id, they cannot both be None")

    participant_id = participant.id

    if event_type == 'AssignmentAccepted':
        pass

    elif event_type == 'AssignmentAbandoned':
        if participant.status == "working":
            participant.end_time = datetime.now()
            participant.status = "abandoned"
            exp.assignment_abandoned(participant=participant)

    elif event_type == 'AssignmentReturned':
        if participant.status == "working":
            participant.end_time = datetime.now()
            participant.status = "returned"
            exp.assignment_returned(participant=participant)

    elif event_type == 'AssignmentSubmitted':
        if participant.status == "working":
            participant.end_time = datetime.now()
            participant.status = "submitted"

            # Approve the assignment.
            exp.recruiter().approve_hit(assignment_id)
            participant.base_pay = config.get(
                'HIT Configuration', 'base_payment')

            # Check that the participant's data is okay.
            worked = exp.data_check(participant=participant)

            # If it isn't, fail their nodes and recruit a replacement.
            if not worked:
                participant.status = "bad_data"
                exp.data_check_failed(participant=participant)
                exp.recruiter().recruit_participants(n=1)
            else:
                # If their data is ok, pay them a bonus.
                # Note that the bonus is paid before the attention check.
                bonus = exp.bonus(participant=participant)
                participant.bonus = bonus
                if bonus >= 0.01:
                    exp.log("Bonus = {}: paying bonus".format(bonus), key)
                    exp.recruiter().reward_bonus(
                        assignment_id,
                        bonus,
                        exp.bonus_reason())
                else:
                    exp.log("Bonus = {}: NOT paying bonus".format(bonus), key)

                # Perform an attention check.
                attended = exp.attention_check(participant=participant)

                # If they fail the attention check, fail nodes and replace.
                if not attended:
                    exp.log("Attention check failed.", key)
                    participant.status = "did_not_attend"
                    exp.attention_check_failed(participant=participant)
                    exp.recruiter().recruit_participants(n=1)
                else:
                    # All good. Possibly recruit more participants.
                    exp.log("All checks passed.", key)
                    participant.status = "approved"
                    exp.submission_successful(participant=participant)
                    exp.recruit()

    elif event_type == "NotificationMissing":
        if participant.status == "working":
            participant.end_time = datetime.now()
            participant.status = "missing_notification"

    else:
        exp.log("Error: unknown event_type {}".format(event_type), key)

    session.commit()