def previously_completed_steps(task, related_steps, **kwargs): """ Assign a new task to the entry-level worker of the specified tasks. If no worker can be assigned, return the unmodified task. Args: task (orchestra.models.Task): The newly created task to assign. related_steps ([str]): List of step slugs from which to attempt to assign a worker. Returns: task (orchestra.models.Task): The modified task object. Raises: orchestra.core.errors.AssignmentPolicyError: Machine steps cannot be included in an assignment policy. """ if related_steps is None: raise AssignmentPolicyError('No related steps given') workflow_version = task.step.workflow_version for step_slug in related_steps: step = workflow_version.steps.get(slug=step_slug) if not step.is_human: raise AssignmentPolicyError('Machine step should not be ' 'member of assignment policy') related_tasks = (Task.objects.filter( step__slug__in=related_steps, project=task.project).select_related('step')) for related_task in related_tasks: entry_level_assignment = assignment_history(related_task).first() if entry_level_assignment and entry_level_assignment.worker: try: return assign_task(entry_level_assignment.worker.id, task.id) except WorkerCertificationError: # Task could not be assigned to related worker, try with # another related worker logger.warning( 'Tried to assign worker %s to step %s, for ' 'which they are not certified', entry_level_assignment.worker.id, task.step.slug, exc_info=True) except Exception: logger.warning('Unable to assign task.', exc_info=True) return task
def _preassign_workers(task, policy_type): """ Assign a new task to a worker according to its assignment policy, leaving the task unchanged if policy not present. Args: task (orchestra.models.Task): The newly created task to assign. policy_type (string): The type of assignment policy to use, from the AssignmentPolicyType Returns: task (orchestra.models.Task): The modified task object. Raises: orchestra.core.errors.AssignmentPolicyError: The specified assignment policy type is not supported or a machine step is given an assignment policy. """ step = task.step policy = step.assignment_policy.get('policy_function', {}).get(policy_type, {}) policy_path = policy.get('path', '') policy_kwargs = policy.get('kwargs', {}) if not step.is_human: if policy: raise AssignmentPolicyError('Machine step should not have ' 'assignment policy.') elif not policy: raise AssignmentPolicyError('Assignment policy incorrectly specified.') else: try: policy_function = locate(policy_path) task = policy_function(task, **policy_kwargs) except Exception as e: raise AssignmentPolicyError(e) return task
def _preassign_workers(task): """ Assign a new task to a worker according to its assignment policy, leaving the task unchanged if policy not present. Args: task (orchestra.models.Task): The newly created task to assign. Returns: task (orchestra.models.Task): The modified task object. Raises: orchestra.core.errors.AssignmentPolicyError: The specified assignment policy type is not supported or a machine step is given an assignment policy. """ step = task.step policy = step.assignment_policy.get('policy') related_steps = step.assignment_policy.get('steps') if not step.is_human: if policy: raise AssignmentPolicyError('Machine step should not have ' 'assignment policy.') elif (policy == 'previously_completed_steps' and related_steps is not None): task = _assign_worker_from_previously_completed_steps( task, related_steps) elif policy == 'anyone_certified': # Leave the task in the awaiting processing pool pass else: raise AssignmentPolicyError('Assignment policy incorrectly specified.') return task