Generator function that yields the jobs in order of their
  completion. Attaches a new listener to each job.

def as_completed(jobs):
  ''' Generator function that yields the jobs in order of their
  completion. Attaches a new listener to each job. '''

  jobs = tuple(jobs)
  event = threading.Event()
  callback = lambda f, ev: event.set()
  [job.add_listener(Job.SUCCESS, callback, once=True) for job in jobs]
  [job.add_listener(Job.ERROR, callback, once=True) for job in jobs]

  while jobs:
    event.wait()
    event.clear()

    jobs, finished = split_list_by(jobs, lambda x: x.finished)
    for job in finished:
      yield job