is_reached is to be called for every object that counts towards the limit.
        - When called with no uid, the Limiter assumes this is a new object and
        unconditionally increments the counter (less CPU and memory usage).
        - When a given object can be passed multiple times, a uid must be provided to
        deduplicate calls. Only the first occurrence of a uid will increment the counter.

        :param uid: (optional) unique identifier of the object, to deduplicate calls
        :returns: boolean, true if limit exceeded

def is_reached(self, uid=None):
        """
        is_reached is to be called for every object that counts towards the limit.
        - When called with no uid, the Limiter assumes this is a new object and
        unconditionally increments the counter (less CPU and memory usage).
        - When a given object can be passed multiple times, a uid must be provided to
        deduplicate calls. Only the first occurrence of a uid will increment the counter.

        :param uid: (optional) unique identifier of the object, to deduplicate calls
        :returns: boolean, true if limit exceeded
        """
        if self.reached_limit:
            return True

        if uid:
            if uid in self.seen:
                return False
            self.count += 1
            self.seen.add(uid)
        else:
            self.count += 1

        if self.count > self.limit:
            if self.warning:
                self.warning(
                    "Check {} exceeded limit of {} {}, ignoring next ones".format(
                        self.check_name, self.limit, self.name
                    )
                )
            self.reached_limit = True
            return True
        return False