Exemple #1
0
    def pick_recruiter(self):
        """Pick the next recruiter to use.

        We use the `Recruitment` table in the db to keep track of
        how many recruitments have been requested using each recruiter.
        We'll use the first one from the specification that
        hasn't already reached its quota.
        """
        counts = dict(
            session.query(Recruitment.recruiter_id, func.count(
                Recruitment.id)).group_by(Recruitment.recruiter_id).all())

        for recruiter_id, target_count in self.spec:
            count = counts.get(recruiter_id, 0)
            if count >= target_count:
                # This recruiter quota was reached;
                # move on to the next one.
                counts[recruiter_id] = count - target_count
                continue
            else:
                # Quota is still available; let's use it.
                break
        else:
            raise Exception('Reached quota for all recruiters. '
                            'Not sure which one to use now.')

        # record the recruitment
        session.add(Recruitment(recruiter_id=recruiter_id))

        # return an instance of the recruiter
        return by_name(recruiter_id)
Exemple #2
0
    def recruiters(self, n=1):
        """Iterator that provides recruiters along with the participant
        count to be recruited for up to `n` participants.

        We use the `Recruitment` table in the db to keep track of
        how many recruitments have been requested using each recruiter.
        We'll use the first one from the specification that
        hasn't already reached its quota.
        """
        recruit_count = 0
        while recruit_count <= n:
            counts = dict(
                session.query(Recruitment.recruiter_id,
                              func.count(Recruitment.id)).group_by(
                                  Recruitment.recruiter_id).all())
            for recruiter_id, target_count in self.spec:
                remaining = 0
                count = counts.get(recruiter_id, 0)
                if count >= target_count:
                    # This recruiter quota was reached;
                    # move on to the next one.
                    counts[recruiter_id] = count - target_count
                    continue
                else:
                    # Quota is still available; let's use it.
                    remaining = target_count - count
                    break
            else:
                return

            num_recruits = min(n - recruit_count, remaining)
            # record the recruitments and commit
            for i in range(num_recruits):
                session.add(Recruitment(recruiter_id=recruiter_id))
            session.commit()

            recruit_count += num_recruits
            yield by_name(recruiter_id), num_recruits