def _run(self):
        """Discovers the health of a service.

        Runs until it is being killed from main program and is responsible to
        put an item into the queue based on the status of the health check.
        The status of service is consider UP after a number of consecutive
        successful health checks, in that case it asks main program to add the
        IP prefix associated with service to BIRD configuration, otherwise ask
        for a removal.
        Rise and fail options prevent unnecessary configuration changes when
        check is flapping.
        """
        up_cnt = 0
        down_cnt = 0
        # The current established state of the service check, it can be
        # either UP or DOWN but only after a number of consecutive successful
        # or unsuccessful health checks.
        check_state = 'Unknown'

        for key, value in self.config.items():
            self.log.debug("%s=%s:%s", key, value, type(value))

        # Service check will abort if it is disabled.
        if self._check_disabled():
            return

        if self.splay_startup is not None:
            sleep_time = float("%.3f" % random.uniform(0, self.splay_startup))
            self.log.info("delaying startup for %ssecs", sleep_time)
            time.sleep(sleep_time)

        interval = self.config['check_interval']
        start_offset = time.time() % interval
        # Go in a loop until we are told to stop
        while True:
            timestamp = time.time()
            if not self._ip_assigned():
                up_cnt = 0
                self.extra['status'] = 'down'
                self.log.warning("status DOWN because %s isn't assigned to "
                                 "loopback interface.",
                                 self.ip_with_prefixlen,
                                 extra=self.extra)
                if check_state != 'DOWN':
                    check_state = 'DOWN'
                    self.log.info("adding %s in the queue",
                                  self.ip_with_prefixlen,
                                  extra=self.extra)
                    self.action.put(self.del_operation)
            elif self._run_check():
                if up_cnt == (self.config['check_rise'] - 1):
                    self.extra['status'] = 'up'
                    self.log.info("status UP", extra=self.extra)
                    # Service exceeded all consecutive checks. Set its state
                    # accordingly and put an item in queue. But do it only if
                    # previous state was different, to prevent unnecessary bird
                    # reloads when a service flaps between states.
                    if check_state != 'UP':
                        check_state = 'UP'
                        self.log.info("adding %s in the queue",
                                      self.ip_with_prefixlen,
                                      extra=self.extra)
                        self.action.put(self.add_operation)
                elif up_cnt < self.config['check_rise']:
                    up_cnt += 1
                    self.log.info("going up %s", up_cnt, extra=self.extra)
                else:
                    self.log.error("up_cnt is higher %s, it's a BUG!",
                                   up_cnt,
                                   extra=self.extra)
                down_cnt = 0
            else:
                if down_cnt == (self.config['check_fail'] - 1):
                    self.extra['status'] = 'down'
                    self.log.info("status DOWN", extra=self.extra)
                    # Service exceeded all consecutive checks.
                    # Set its state accordingly and put an item in queue.
                    # But do it only if previous state was different, to
                    # prevent unnecessary bird reloads when a service flaps
                    # between states
                    if check_state != 'DOWN':
                        check_state = 'DOWN'
                        self.log.info("adding %s in the queue",
                                      self.ip_with_prefixlen,
                                      extra=self.extra)
                        self.action.put(self.del_operation)
                elif down_cnt < self.config['check_fail']:
                    down_cnt += 1
                    self.log.info("going down %s", down_cnt, extra=self.extra)
                else:
                    self.log.error("up_cnt is higher %s, it's a BUG!",
                                   up_cnt,
                                   extra=self.extra)
                up_cnt = 0

            self.log.info("wall clock time %.3fms",
                          (time.time() - timestamp) * 1000,
                          extra=self.extra)

            # calculate sleep time
            sleep = start_offset - time.time() % interval
            if sleep < 0:
                sleep += interval
            self.log.debug("sleeping for %.3fsecs", sleep, extra=self.extra)
            time.sleep(sleep)