예제 #1
0
    def _poll_up_down_queue(self, timeout: float) -> bool: # returns "should keep running"

        poll_timeout = Timeout(timeout)
        while not poll_timeout.expired:

            pop_timeout = Timeout(min(poll_timeout.remain, 1.0))
            while not pop_timeout.expired:

                event = pop_timeout.pop(self._up_down_queue)
                if event is not None:
                    try:

                        node, cage, up_down, *args = event
                        if up_down == "up":

                            location, probe_result = args

                            # add the cage to cages known to be up and schedule
                            # application notification call if it was down or
                            # returned a different probe result

                            cage_info = self._up_cages.setdefault(cage, {}).setdefault(node, {})
                            if not cage_info or cage_info["probe_result"] != probe_result:
                                self._schedule_up_down_event(node, cage, "up", probe_result)
                            cage_info.update(location = location, probe_result = probe_result)

                        elif up_down == "down":

                            # remove the cage from cages known to be up and schedule
                            # application notification call it was up

                            if self._up_cages.setdefault(cage, {}).pop(node, None):
                                self._schedule_up_down_event(node, cage, "down")

                    except:
                        pmnc.log.error(exc_string()) # log and ignore

            if current_thread().stopped():
                return False

        return True
예제 #2
0
    def _poll_up_down_queue(self, timeout: float) -> bool:  # returns "should keep running"

        poll_timeout = Timeout(timeout)
        while not poll_timeout.expired:

            pop_timeout = Timeout(min(poll_timeout.remain, 1.0))
            while not pop_timeout.expired:

                event = pop_timeout.pop(self._up_down_queue)
                if event is not None:
                    try:

                        node, cage, up_down, *args = event
                        if up_down == "up":

                            location, probe_result = args

                            # add the cage to cages known to be up and schedule
                            # application notification call if it was down or
                            # returned a different probe result

                            cage_info = self._up_cages.setdefault(cage, {}).setdefault(node, {})
                            if not cage_info or cage_info["probe_result"] != probe_result:
                                self._schedule_up_down_event(node, cage, "up", probe_result)
                            cage_info.update(location=location, probe_result=probe_result)

                        elif up_down == "down":

                            # remove the cage from cages known to be up and schedule
                            # application notification call it was up

                            if self._up_cages.setdefault(cage, {}).pop(node, None):
                                self._schedule_up_down_event(node, cage, "down")

                    except:
                        pmnc.log.error(exc_string())  # log and ignore

            if current_thread().stopped():
                return False

        return True
예제 #3
0
    def _maintainer_proc(self):

        while not current_thread().stopped():

            while True: # keep trying to start the adapter
                try:
                    self._start_adapter("interface", self._name, Timeout(15.0))
                except:
                    pmnc.log.error(exc_string())
                    failure_timeout = max(self._request_timeout, 30.0)
                    if current_thread().stopped(failure_timeout):
                        return
                else:
                    break

            # now that the adapter is running, keep receiving messages
            # until the adapter exits or the interface is ceased

            try:

                try:

                    while self._adapter_running():

                        # even when the queue is idle, the adapter should be sending in a ping once in 3 seconds

                        receive_timeout = Timeout(self._request_timeout + 3.0)
                        pkt = receive_timeout.pop(self._stdout_queue)
                        if pkt is None:
                            raise Exception("adapter process failed to produce a message")

                        if "XPmncError" in pkt: # adapter reports error, abort
                            raise Exception(pkt["XPmncError"])

                        request_id = pkt.pop("XPmncRequestID")

                        if current_thread().stopped(): # any command after shutdown gets an EXIT response
                            response = Packet(XPmncResponse = "EXIT", XPmncRequestID = request_id)
                            self._stdin_queue.push(response)
                            break

                        request = pkt.pop("XPmncRequest")

                        if request == "NOOP": # ping always gets an OK response
                            response = Packet(XPmncResponse = "OK", XPmncRequestID = request_id)
                            self._stdin_queue.push(response)
                        elif request == "RECEIVE": # process an incoming message
                            message_id = pkt["JMSMessageID"]
                            if message_id not in self._processed_messages: # don't process the message again
                                success = self._process_message(message_id, pkt, receive_timeout.remain)
                            else:
                                success = True
                            response = Packet(XPmncResponse = success and "COMMIT" or "ROLLBACK",
                                              XPmncRequestID = request_id, XPmncMessageID = message_id)
                            self._stdin_queue.push(response)
                        else:
                            raise Exception("invalid request")

                finally:
                    self._stop_adapter(Timeout(5.0)) # make sure the adapter is not running

            except:
                pmnc.log.error(exc_string()) # log and ignore