docs: 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()