def wait(self):
     for tag in self.tags:
         if tag not in self.active_requests:
             self.active_requests[tag] = self.comm.irecv(tag=tag)
     requests = mpi.RequestList(self.active_requests.values())
     data, status, index = mpi.wait_any(requests)
     del self.active_requests[status.tag]
     return status, data
def rank0():
    sent_histories = (mpi.size - 1) * 15
    print "sending %d packets on their way" % sent_histories
    send_reqs = mpi.RequestList()
    for i in range(sent_histories):
        dest = random.randrange(1, mpi.size)
        send_reqs.append(mpi.world.isend(dest, TAG_DATA, []))

    mpi.wait_all(send_reqs)

    completed_histories = []
    progress_reports = {}
    dead_kids = []

    tgl = TagGroupListener(
        mpi.world, [TAG_DATA, TAG_DEBUG, TAG_PROGRESS_REPORT, TAG_TERMINATE])

    def is_complete():
        for i in progress_reports.values():
            if i != sent_histories:
                return False
        return len(dead_kids) == mpi.size - 1

    while True:
        status, data = tgl.wait()

        if status.tag == TAG_DATA:
            # print "received completed history %s from %d" % (data, status.source)
            completed_histories.append(data)
            if len(completed_histories) == sent_histories:
                print "all histories received, exiting"
                for rank in range(1, mpi.size):
                    mpi.world.send(rank, TAG_TERMINATE, None)
        elif status.tag == TAG_PROGRESS_REPORT:
            progress_reports[len(data)] = progress_reports.get(len(data),
                                                               0) + 1
        elif status.tag == TAG_DEBUG:
            print "[DBG %d] %s" % (status.source, data)
        elif status.tag == TAG_TERMINATE:
            dead_kids.append(status.source)
        else:
            print "unexpected tag %d from %d" % (status.tag, status.source)

        if is_complete():
            break

    print "OK"