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
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
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