def reconnect(self, retry = True): if not config.REMOTE: return if not self.connection.is_closed: return quorum.info("Re-connecting to the AMQP system") self.connect(queue = self.queue, retry = retry)
def reconnect(self, retry=True): if not config.REMOTE: return if not self.connection.is_closed: return quorum.info("Re-connecting to the AMQP system") self.connect(queue=self.queue, retry=retry)
def connect(self, queue = "default", retry = True): if not config.REMOTE: return quorum.info("Connecting to the AMQP system") while True: try: self.connection = quorum.get_amqp(force = True) self.channel = self.connection.channel() self.channel.queue_declare(queue = queue, durable = True) self.queue = queue break except Exception as exception: if not retry: raise quorum.error( "Exception while connecting - %s" % quorum.legacy.UNICODE(exception), log_trace = True ) quorum.info("Sleeping %d seconds before connect retry" % RETRY_TIMEOUT) time.sleep(RETRY_TIMEOUT)
def connect(self, queue="default", retry=True): if not config.REMOTE: return quorum.info("Connecting to the AMQP system") while True: try: self.connection = quorum.get_amqp(force=True) self.channel = self.connection.channel() self.channel.queue_declare(queue=queue, durable=True) self.queue = queue break except Exception as exception: if not retry: raise quorum.error("Exception while connecting - %s" % quorum.legacy.UNICODE(exception), log_trace=True) quorum.info("Sleeping %d seconds before connect retry" % RETRY_TIMEOUT) time.sleep(RETRY_TIMEOUT)
def connect(self, queue="default"): if not config.REMOTE: return while True: try: quorum.debug("Starting loop cycle in slave ...") self.connection = quorum.get_amqp(force=True) self.channel = self.connection.channel() self.channel.queue_declare(queue=queue, durable=True) self.channel.basic_qos(prefetch_count=1) self.channel.basic_consume(queue=queue, on_message_callback=self.callback) self.channel.start_consuming() except Exception as exception: quorum.error("Exception while executing - %s" % quorum.legacy.UNICODE(exception), log_trace=True) quorum.info("Sleeping %d seconds before consume retry" % RETRY_TIMEOUT) time.sleep(RETRY_TIMEOUT)
def callback(self, channel, method, properties, body): # prints a debug message about the callback call for the message, this # may be used latter for debugging purposes (as requested) quorum.debug("Received callback for message") # loads the contents of the body that is going to be submitted this # is considered the payload of the document to be submitted document = json.loads(body) # retrieves the various attributes of the document that is going to # be submitted, making sure that the issue date is correctly formatted type = document["_class"] object_id = document["object_id"] representation = document["representation"] issue_date = document["issue_date"] issue_date_d = datetime.datetime.utcfromtimestamp(issue_date) issue_date_s = issue_date_d.strftime("%d %b %Y %H:%M:%S") # verifies if the document is considered to be outdated (timeout passed) # in case it's returns immediately printing a message outdated = not properties.timestamp or\ properties.timestamp < time.time() - MESSAGE_TIMEOUT if outdated: channel.basic_ack(delivery_tag=method.delivery_tag) quorum.info("Canceling/Dropping %s - %s (%s)" % (type, representation, issue_date_s)) return # retrieves the current time and uses it to print debug information # about the current document submission to at quorum.info("Submitting %s - %s (%s)" % (type, representation, issue_date_s)) # resolves the method for the currently retrieved data type (class) # this should raise an exception in case the type is invalid api_method = self._resolve_method(type) try: # calls the proper method for the submission of the document # described by the provided object id, in case there's a problem # in the request an exception should be raised and handled properly api_method(object_id) except Exception as exception: quorum.error("Exception while submitting document - %s" % quorum.legacy.UNICODE(exception)) retries = properties.priority or 0 retries -= 1 properties.priority = retries if retries >= 0: self.channel.basic_publish(exchange="", routing_key=config.QUEUE, body=body, properties=properties) quorum.error( "Re-queueing for latter consumption (%d retries pending)" % retries) else: quorum.error( "No more retries left, the document will be discarded") else: quorum.info("Document submitted with success") # marks the message as acknowledged in the message queue server # and then prints a debug message about the action channel.basic_ack(delivery_tag=method.delivery_tag) quorum.debug("Marked as acknowledged in message queue")
def execute(self): # in case the current instance is not configured according to # the remote rules the queuing operation is ignored, and so # the control flow returns immediately if not config.REMOTE: return # creates a values map structure to retrieve the complete # set of inbound documents that have not yet been submitted # to at for the flush operation kwargs = { "session_id" : self.session_id, "filter_string" : "", "start_record" : 0, "number_records" : NUMBER_RECORDS, "sort" : "issue_date:ascending", "filters[]" : [ "issue_date:greater:1356998400", "submitted_at:equals:2", "document_type:in:1;3" ] } documents = self.api.list_signed_documents(**kwargs) valid_documents = [value for value in documents\ if value["_class"] in config.AT_SUBMIT_TYPES] # starts the counter value to zero, so that we're able to count # the number of messages that have been successfully queued to # the remote queueing mechanism (for debugging) count = 0 # iterates over all the valid documents that have been found # as not submitted and creates a task for their submission # then adds the task to the AMQP queue to be processed for document in valid_documents: try: # tries to run the basic publish operation, this operation # may fail for a variety of reasons including errors in the # underlying library so a reconnection is attempted in case # there's an exception raised under this operation self.channel.basic_publish( exchange = "", routing_key = config.QUEUE, body = json.dumps(document), properties = quorum.properties_amqp( delivery_mode = 2, priority = MESSAGE_RETRIES, expiration = str(MESSAGE_TIMEOUT * 1000), timestamp = time.time() ) ) count += 1 except Exception as exception: # prints a warning message about the exception that has just occurred # so that it's possible to act on it quorum.warning( "Exception in publish (will re-connect) - %s" % quorum.legacy.UNICODE(exception), log_trace = True ) # re-tries to connect with the AMQP channels using the currently # pre-defined queue system, this is a fallback of the error self.reconnect() # prints an information message about the new documents that # have been queued for submission by the "slaves" quorum.info("Queued %d (out of %d) documents for submission" % (count, len(valid_documents)))
def disconnect(self): if not config.REMOTE: return quorum.info("Disconnected from the AMQP system") self.connection.close()
def execute(self): # in case the current instance is not configured according to # the remote rules the queuing operation is ignored, and so # the control flow returns immediately if not config.REMOTE: return # creates a values map structure to retrieve the complete # set of inbound documents that have not yet been submitted # to at for the flush operation kwargs = { "session_id": self.session_id, "filter_string": "", "start_record": 0, "number_records": NUMBER_RECORDS, "sort": "issue_date:ascending", "filters[]": [ "issue_date:greater:1356998400", "submitted_at:equals:2", "document_type:in:1;3" ] } documents = self.api.list_signed_documents(**kwargs) valid_documents = [value for value in documents\ if value["_class"] in config.AT_SUBMIT_TYPES] # starts the counter value to zero, so that we're able to count # the number of messages that have been successfully queued to # the remote queueing mechanism (for debugging) count = 0 # iterates over all the valid documents that have been found # as not submitted and creates a task for their submission # then adds the task to the AMQP queue to be processed for document in valid_documents: try: # tries to run the basic publish operation, this operation # may fail for a variety of reasons including errors in the # underlying library so a reconnection is attempted in case # there's an exception raised under this operation self.channel.basic_publish(exchange="", routing_key=config.QUEUE, body=json.dumps(document), properties=quorum.properties_amqp( delivery_mode=2, priority=MESSAGE_RETRIES, expiration=str(MESSAGE_TIMEOUT * 1000), timestamp=time.time())) count += 1 except Exception as exception: # prints a warning message about the exception that has just occurred # so that it's possible to act on it quorum.warning("Exception in publish (will re-connect) - %s" % quorum.legacy.UNICODE(exception), log_trace=True) # re-tries to connect with the AMQP channels using the currently # pre-defined queue system, this is a fallback of the error self.reconnect() # prints an information message about the new documents that # have been queued for submission by the "slaves" quorum.info("Queued %d (out of %d) documents for submission" % (count, len(valid_documents)))