def handle(self, bundle: TransactionBundle, statistics: StatisticsSet): """ The main dispatcher for incoming messages. :param bundle: The transaction bundle :param statistics: Container for shared memory with statistics counters :returns: The message to reply with """ if not bundle.request: # Nothing to do... return None # Update the allow_rapid_commit flag bundle.allow_rapid_commit = self.allow_rapid_commit # Count the incoming message type statistics.count_message_in(bundle.request.message_type) # Log what we are doing (low-detail, so not DEBUG_HANDLING here) logger.debug("Handling {}".format(bundle)) # Collect the handlers handlers = self.get_handlers(bundle) # Analyse pre for handler in handlers: # noinspection PyBroadException try: handler.analyse_pre(bundle) except: # Ignore all errors, analysis isn't that important pass try: # Pre-process the request for handler in handlers: handler.pre(bundle) # Init the response self.init_response(bundle) # Process the request for handler in handlers: logger.log(DEBUG_HANDLING, "Applying {}".format(handler)) handler.handle(bundle) # Post-process the request for handler in handlers: handler.post(bundle) except ForOtherServerError as e: # Specific form of CannotRespondError that should have its own log message message = str(e) or 'Message is for another server' logger.debug("{}: ignoring".format(message)) statistics.count_for_other_server() bundle.response = None except CannotRespondError as e: message = str(e) or 'Cannot respond to this message' logger.warning("{}: ignoring".format(message)) statistics.count_do_not_respond() bundle.response = None except UseMulticastError: logger.debug("Unicast request received when multicast is required: informing client") statistics.count_use_multicast() bundle.response = self.construct_use_multicast_reply(bundle) # Analyse post for handler in handlers: # noinspection PyBroadException try: handler.analyse_post(bundle) except: # Ignore all errors, analysis isn't that important pass if bundle.response: logger.log(DEBUG_HANDLING, "Responding with {}".format(bundle.response.__class__.__name__)) # Count the outgoing message type statistics.count_message_out(bundle.response.message_type) else: logger.log(DEBUG_HANDLING, "Not responding")
def handle(self, bundle: TransactionBundle, statistics: StatisticsSet): """ The main dispatcher for incoming messages. :param bundle: The transaction bundle :param statistics: Container for shared memory with statistics counters :returns: The message to reply with """ if not bundle.request: # Nothing to do... return None # Update the allow_rapid_commit flag bundle.allow_rapid_commit = self.allow_rapid_commit # Count the incoming message type statistics.count_message_in(bundle.request.message_type) # Log what we are doing (low-detail, so not DEBUG_HANDLING here) logger.debug("Handling {}".format(bundle)) # Collect the handlers handlers = self.get_handlers(bundle) # Analyse pre for handler in handlers: # noinspection PyBroadException try: handler.analyse_pre(bundle) except: # Ignore all errors, analysis isn't that important logger.exception("{} pre analysis failed".format(handler.__class__.__name__)) try: # Pre-process the request for handler in handlers: handler.pre(bundle) # Init the response self.init_response(bundle) # Process the request for handler in handlers: logger.log(DEBUG_HANDLING, "Applying {}".format(handler)) handler.handle(bundle) # Post-process the request for handler in handlers: handler.post(bundle) except ForOtherServerError as e: # Specific form of CannotRespondError that should have its own log message message = str(e) or 'Message is for another server' logger.debug("{}: ignoring".format(message)) statistics.count_for_other_server() bundle.response = None except CannotRespondError as e: message = str(e) or 'Cannot respond to this message' logger.warning("{}: ignoring".format(message)) statistics.count_do_not_respond() bundle.response = None except UseMulticastError: logger.debug("Unicast request received when multicast is required: informing client") statistics.count_use_multicast() bundle.response = self.construct_use_multicast_reply(bundle) except ReplyWithStatusError as e: # Leasequery has its own reply message type if isinstance(e, ReplyWithLeasequeryError): bundle.response = self.construct_leasequery_status_reply(bundle, e.option) else: bundle.response = self.construct_plain_status_reply(bundle, e.option) logger.warning("Replying with {}".format(e)) # Update the right counter based on the status code if e.option.status_code == STATUS_UNKNOWN_QUERY_TYPE: statistics.count_unknown_query_type() elif e.option.status_code == STATUS_MALFORMED_QUERY: statistics.count_malformed_query() elif e.option.status_code == STATUS_NOT_ALLOWED: statistics.count_not_allowed() else: statistics.count_other_error() # Analyse post for handler in handlers: # noinspection PyBroadException try: handler.analyse_post(bundle) except: # Ignore all errors, analysis isn't that important logger.exception("{} post analysis failed".format(handler.__class__.__name__)) if bundle.response: logger.log(DEBUG_HANDLING, "Responding with {}".format(bundle.response.__class__.__name__)) # Count the outgoing message type statistics.count_message_out(bundle.response.message_type) else: logger.log(DEBUG_HANDLING, "Not responding")
def handle(self, bundle: TransactionBundle, statistics: StatisticsSet): """ The main dispatcher for incoming messages. :param bundle: The transaction bundle :param statistics: Container for shared memory with statistics counters """ if not bundle.request: # Nothing to do... return # Update the allow_rapid_commit flag bundle.allow_rapid_commit = self.allow_rapid_commit # Count the incoming message type statistics.count_message_in(bundle.request.message_type) # Log what we are doing (low-detail, so not DEBUG_HANDLING here) logger.debug("Handling {}".format(bundle)) # Collect the handlers handlers = self.get_handlers(bundle) # Analyse pre for handler in handlers: # noinspection PyBroadException try: handler.analyse_pre(bundle) except: # Ignore all errors, analysis isn't that important logger.exception("{} pre analysis failed".format( handler.__class__.__name__)) try: # Pre-process the request for handler in handlers: handler.pre(bundle) # Init the response self.init_response(bundle) # Process the request for handler in handlers: logger.log(DEBUG_HANDLING, "Applying {}".format(handler)) handler.handle(bundle) # Post-process the request for handler in handlers: handler.post(bundle) except ForOtherServerError as e: # Specific form of CannotRespondError that should have its own log message message = str(e) or 'Message is for another server' logger.debug("{}: ignoring".format(message)) statistics.count_for_other_server() bundle.response = None except CannotRespondError as e: message = str(e) or 'Cannot respond to this message' logger.warning("{}: ignoring".format(message)) statistics.count_do_not_respond() bundle.response = None except UseMulticastError: logger.debug( "Unicast request received when multicast is required: informing client" ) statistics.count_use_multicast() bundle.response = self.construct_use_multicast_reply(bundle) except ReplyWithStatusError as e: # Leasequery has its own reply message type if isinstance(e, ReplyWithLeasequeryError): bundle.response = self.construct_leasequery_status_reply( bundle, e.option) else: bundle.response = self.construct_plain_status_reply( bundle, e.option) logger.warning("Replying with {}".format(e)) # Update the right counter based on the status code if e.option.status_code == STATUS_UNKNOWN_QUERY_TYPE: statistics.count_unknown_query_type() elif e.option.status_code == STATUS_MALFORMED_QUERY: statistics.count_malformed_query() elif e.option.status_code == STATUS_NOT_ALLOWED: statistics.count_not_allowed() else: statistics.count_other_error() # Analyse post for handler in handlers: # noinspection PyBroadException try: handler.analyse_post(bundle) except: # Ignore all errors, analysis isn't that important logger.exception("{} post analysis failed".format( handler.__class__.__name__)) if bundle.response: logger.log( DEBUG_HANDLING, "Responding with {}".format( bundle.response.__class__.__name__)) # Count the outgoing message type statistics.count_message_out(bundle.response.message_type) else: logger.log(DEBUG_HANDLING, "Not responding")