def _compute_job_priorities(self, job_list):
    """Walks the dependency graph breadth-first, starting from the most dependent tasks,
     and computes the job priority as the sum of the jobs sizes along the critical path."""

    job_size = {job.key: job.size for job in job_list}
    job_priority = defaultdict(int)

    bfs_queue = deque()
    for job in job_list:
      if len(self._dependees[job.key]) == 0:
        job_priority[job.key] = job_size[job.key]
        bfs_queue.append(job.key)

    satisfied_dependees_count = defaultdict(int)
    while len(bfs_queue) > 0:
      job_key = bfs_queue.popleft()
      for dependency_key in self._dependencies[job_key]:
        job_priority[dependency_key] = \
          max(job_priority[dependency_key],
              job_size[dependency_key] + job_priority[job_key])
        satisfied_dependees_count[dependency_key] += 1
        if satisfied_dependees_count[dependency_key] == len(self._dependees[dependency_key]):
          bfs_queue.append(dependency_key)

    return job_priority
Walks the dependency graph breadth-first, starting from the most dependent tasks,
     and computes the job priority as the sum of the jobs sizes along the critical path.