示例#1
0
class Dispatcher:
    debug = False

    def __init__(self, debug=False):
        self.debug = debug
        self._init()

    def wait(self):
        log.info("Waiting for messages..")
        timeout = 600
        while True:
            try:
                # Close the Django DB connection before processing
                # every incoming message. This plays nicely with
                # DB connection pooling, if enabled and allows
                # the dispatcher to recover from broken connections
                # gracefully.
                close_connection()
                msg = self.client.basic_wait(timeout=timeout)
                if not msg:
                    log.warning(
                        "Idle connection for %d seconds. Will connect"
                        " to a different host. Verify that"
                        " snf-ganeti-eventd is running!!", timeout)
                    self.client.reconnect()
            except SystemExit:
                break
            except Exception as e:
                log.exception("Caught unexpected exception: %s", e)

        self.client.basic_cancel()
        self.client.close()

    def _init(self):
        log.info("Initializing")

        self.client = AMQPClient(logger=log_amqp)
        # Connect to AMQP host
        self.client.connect()

        # Declare queues and exchanges
        exchange = settings.EXCHANGE_GANETI
        exchange_dl = queues.convert_exchange_to_dead(exchange)
        self.client.exchange_declare(exchange=exchange, type="topic")
        self.client.exchange_declare(exchange=exchange_dl, type="topic")

        for queue in queues.QUEUES:
            # Queues are mirrored to all RabbitMQ brokers
            self.client.queue_declare(queue=queue,
                                      mirrored=True,
                                      dead_letter_exchange=exchange_dl)
            # Declare the corresponding dead-letter queue
            queue_dl = queues.convert_queue_to_dead(queue)
            self.client.queue_declare(queue=queue_dl, mirrored=True)

        # Bind queues to handler methods
        for binding in queues.BINDINGS:
            try:
                callback = getattr(callbacks, binding[3])
            except AttributeError:
                log.error("Cannot find callback %s", binding[3])
                raise SystemExit(1)
            queue = binding[0]
            exchange = binding[1]
            routing_key = binding[2]

            self.client.queue_bind(queue=queue,
                                   exchange=exchange,
                                   routing_key=routing_key)

            self.client.basic_consume(queue=binding[0],
                                      callback=callback,
                                      prefetch_count=5)

            queue_dl = queues.convert_queue_to_dead(queue)
            exchange_dl = queues.convert_exchange_to_dead(exchange)
            # Bind the corresponding dead-letter queue
            self.client.queue_bind(queue=queue_dl,
                                   exchange=exchange_dl,
                                   routing_key=routing_key)

            log.debug("Binding %s(%s) to queue %s with handler %s", exchange,
                      routing_key, queue, binding[3])
示例#2
0
class Dispatcher:
    debug = False

    def __init__(self, debug=False):
        self.debug = debug
        self._init()

    def wait(self):
        log.info("Waiting for messages..")
        timeout = DISPATCHER_RECONNECT_TIMEOUT
        while True:
            try:
                # Close the Django DB connection before processing
                # every incoming message. This plays nicely with
                # DB connection pooling, if enabled and allows
                # the dispatcher to recover from broken connections
                # gracefully.
                close_connection()
                msg = self.client.basic_wait(timeout=timeout)
                if not msg:
                    log.warning(
                        "Idle connection for %d seconds. Will connect"
                        " to a different host. Verify that"
                        " snf-ganeti-eventd is running!!", timeout)
                    self.client.reconnect(timeout=1)
            except AMQPConnectionError as e:
                log.error("AMQP connection failed: %s" % e)
                log.warning("Sleeping for %d seconds before retrying to "
                            "connect to an AMQP broker" %
                            DISPATCHER_FAILED_CONNECTION_WAIT)
                time.sleep(DISPATCHER_FAILED_CONNECTION_WAIT)
            except select.error as e:
                if e[0] != errno.EINTR:
                    log.exception("Caught unexpected exception: %s", e)
                    log.warning("Sleeping for %d seconds before retrying to "
                                "connect to an AMQP broker" %
                                DISPATCHER_FAILED_CONNECTION_WAIT)
                    time.sleep(DISPATCHER_FAILED_CONNECTION_WAIT)
                else:
                    break
            except (SystemExit, KeyboardInterrupt):
                break
            except Exception as e:
                log.exception("Caught unexpected exception: %s", e)
                log.warning("Sleeping for %d seconds before retrying to "
                            "connect to an AMQP broker" %
                            DISPATCHER_FAILED_CONNECTION_WAIT)
                time.sleep(DISPATCHER_FAILED_CONNECTION_WAIT)

        log.info("Clean up AMQP connection before exit")
        self.client.basic_cancel(timeout=1)
        self.client.close(timeout=1)

    def _init(self):
        log.info("Initializing")

        # Set confirm buffer to 1 for heartbeat messages
        self.client = AMQPClient(logger=log_amqp, confirm_buffer=1)
        # Connect to AMQP host
        self.client.connect()

        # Declare queues and exchanges
        exchange = settings.EXCHANGE_GANETI
        exchange_dl = queues.convert_exchange_to_dead(exchange)
        self.client.exchange_declare(exchange=exchange, type="topic")
        self.client.exchange_declare(exchange=exchange_dl, type="topic")
        for queue in queues.QUEUES:
            # Queues are mirrored to all RabbitMQ brokers
            self.client.queue_declare(queue=queue,
                                      mirrored=True,
                                      dead_letter_exchange=exchange_dl)
            # Declare the corresponding dead-letter queue
            queue_dl = queues.convert_queue_to_dead(queue)
            self.client.queue_declare(queue=queue_dl, mirrored=True)

        # Bind queues to handler methods
        for binding in queues.BINDINGS:
            try:
                callback = getattr(callbacks, binding[3])
            except AttributeError:
                log.error("Cannot find callback %s", binding[3])
                raise SystemExit(1)
            queue = binding[0]
            exchange = binding[1]
            routing_key = binding[2]

            self.client.queue_bind(queue=queue,
                                   exchange=exchange,
                                   routing_key=routing_key)

            self.client.basic_consume(queue=binding[0],
                                      callback=callback,
                                      prefetch_count=5)

            queue_dl = queues.convert_queue_to_dead(queue)
            exchange_dl = queues.convert_exchange_to_dead(exchange)
            # Bind the corresponding dead-letter queue
            self.client.queue_bind(queue=queue_dl,
                                   exchange=exchange_dl,
                                   routing_key=routing_key)

            log.debug("Binding %s(%s) to queue %s with handler %s", exchange,
                      routing_key, queue, binding[3])

        # Declare the queue that will be used for receiving requests, e.g. a
        # status check request
        hostname, pid = get_hostname(), os.getpid()
        queue = queues.get_dispatcher_request_queue(hostname, pid)
        self.client.queue_declare(queue=queue,
                                  mirrored=True,
                                  ttl=REQUEST_QUEUE_TTL)
        self.client.basic_consume(queue=queue, callback=handle_request)
        log.debug("Binding %s(%s) to queue %s with handler 'hadle_request'",
                  exchange, routing_key, queue)
示例#3
0
class Dispatcher:
    debug = False

    def __init__(self, debug=False):
        self.debug = debug
        self._init()

    def wait(self):
        log.info("Waiting for messages..")
        timeout = 600
        while True:
            try:
                # Close the Django DB connection before processing
                # every incoming message. This plays nicely with
                # DB connection pooling, if enabled and allows
                # the dispatcher to recover from broken connections
                # gracefully.
                close_connection()
                msg = self.client.basic_wait(timeout=timeout)
                if not msg:
                    log.warning(
                        "Idle connection for %d seconds. Will connect"
                        " to a different host. Verify that"
                        " snf-ganeti-eventd is running!!",
                        timeout,
                    )
                    self.client.reconnect()
            except SystemExit:
                break
            except Exception as e:
                log.exception("Caught unexpected exception: %s", e)

        self.client.basic_cancel()
        self.client.close()

    def _init(self):
        log.info("Initializing")

        self.client = AMQPClient(logger=log_amqp)
        # Connect to AMQP host
        self.client.connect()

        # Declare queues and exchanges
        exchange = settings.EXCHANGE_GANETI
        exchange_dl = queues.convert_exchange_to_dead(exchange)
        self.client.exchange_declare(exchange=exchange, type="topic")
        self.client.exchange_declare(exchange=exchange_dl, type="topic")

        for queue in queues.QUEUES:
            # Queues are mirrored to all RabbitMQ brokers
            self.client.queue_declare(queue=queue, mirrored=True, dead_letter_exchange=exchange_dl)
            # Declare the corresponding dead-letter queue
            queue_dl = queues.convert_queue_to_dead(queue)
            self.client.queue_declare(queue=queue_dl, mirrored=True)

        # Bind queues to handler methods
        for binding in queues.BINDINGS:
            try:
                callback = getattr(callbacks, binding[3])
            except AttributeError:
                log.error("Cannot find callback %s", binding[3])
                raise SystemExit(1)
            queue = binding[0]
            exchange = binding[1]
            routing_key = binding[2]

            self.client.queue_bind(queue=queue, exchange=exchange, routing_key=routing_key)

            self.client.basic_consume(queue=binding[0], callback=callback, prefetch_count=5)

            queue_dl = queues.convert_queue_to_dead(queue)
            exchange_dl = queues.convert_exchange_to_dead(exchange)
            # Bind the corresponding dead-letter queue
            self.client.queue_bind(queue=queue_dl, exchange=exchange_dl, routing_key=routing_key)

            log.debug("Binding %s(%s) to queue %s with handler %s", exchange, routing_key, queue, binding[3])
示例#4
0
def main():
    parser = OptionParser()
    parser.add_option('-v', '--verbose', action='store_true', default=False,
                      dest='verbose', help='Enable verbose logging')
    parser.add_option('--host', default=BROKER_HOST, dest='host',
                      help='RabbitMQ host (default: %s)' % BROKER_HOST)
    parser.add_option('--port', default=BROKER_PORT, dest='port',
                      help='RabbitMQ port (default: %s)' % BROKER_PORT, type='int')
    parser.add_option('--user', default=BROKER_USER, dest='user',
                      help='RabbitMQ user (default: %s)' % BROKER_USER)
    parser.add_option('--password', default=BROKER_PASSWORD, dest='password',
                      help='RabbitMQ password (default: %s)' % BROKER_PASSWORD)
    parser.add_option('--vhost', default=BROKER_VHOST, dest='vhost',
                      help='RabbitMQ vhost (default: %s)' % BROKER_VHOST)
    parser.add_option('--queue', default=CONSUMER_QUEUE, dest='queue',
                      help='RabbitMQ queue (default: %s)' % CONSUMER_QUEUE)
    parser.add_option('--exchange', default=CONSUMER_EXCHANGE, dest='exchange',
                      help='RabbitMQ exchange (default: %s)' % CONSUMER_EXCHANGE)
    parser.add_option('--key', default=CONSUMER_KEY, dest='key',
                      help='RabbitMQ key (default: %s)' % CONSUMER_KEY)
    parser.add_option('--callback', default=None, dest='callback',
                      help='Callback function to consume messages')
    parser.add_option('--test', action='store_true', default=False,
                      dest='test', help='Produce a dummy message for testing')
    opts, args = parser.parse_args()

    DEBUG = False
    if opts.verbose:
        DEBUG = True
    logging.basicConfig(
        format='%(asctime)s [%(levelname)s] %(name)s %(message)s',
        datefmt='%Y-%m-%d %H:%M:%S',
        level=logging.DEBUG if DEBUG else logging.INFO)
    logger = logging.getLogger('dispatcher')

    host =  'amqp://%s:%s@%s:%s' % (opts.user, opts.password, opts.host, opts.port)
    queue = opts.queue
    key = opts.key
    exchange = opts.exchange
    
    client = AMQPClient(hosts=[host])
    client.connect()

    if opts.test:
        client.exchange_declare(exchange=exchange,
                                type='topic')
        client.basic_publish(exchange=exchange,
                             routing_key=key,
                             body= json.dumps({"test": "0123456789"}))
        client.close()
        sys.exit()

    callback = None
    if opts.callback:
        cb = opts.callback.rsplit('.', 1)
        if len(cb) == 2:
            __import__(cb[0])
            cb_module = sys.modules[cb[0]]
            callback = getattr(cb_module, cb[1])

    def handle_message(client, msg):
        logger.debug('%s', msg)
        if callback:
            callback(msg)
        client.basic_ack(msg)

    client.queue_declare(queue=queue)
    client.queue_bind(queue=queue,
                      exchange=exchange,
                      routing_key=key)

    client.basic_consume(queue=queue, callback=handle_message)

    try:
        while True:
            client.basic_wait()
    except KeyboardInterrupt:
        pass
    finally:
        client.close()
示例#5
0
def main():
    parser = OptionParser()
    parser.add_option('-v',
                      '--verbose',
                      action='store_true',
                      default=False,
                      dest='verbose',
                      help='Enable verbose logging')
    parser.add_option('--host',
                      default=BROKER_HOST,
                      dest='host',
                      help='RabbitMQ host (default: %s)' % BROKER_HOST)
    parser.add_option('--port',
                      default=BROKER_PORT,
                      dest='port',
                      help='RabbitMQ port (default: %s)' % BROKER_PORT,
                      type='int')
    parser.add_option('--user',
                      default=BROKER_USER,
                      dest='user',
                      help='RabbitMQ user (default: %s)' % BROKER_USER)
    parser.add_option('--password',
                      default=BROKER_PASSWORD,
                      dest='password',
                      help='RabbitMQ password (default: %s)' % BROKER_PASSWORD)
    parser.add_option('--vhost',
                      default=BROKER_VHOST,
                      dest='vhost',
                      help='RabbitMQ vhost (default: %s)' % BROKER_VHOST)
    parser.add_option('--queue',
                      default=CONSUMER_QUEUE,
                      dest='queue',
                      help='RabbitMQ queue (default: %s)' % CONSUMER_QUEUE)
    parser.add_option('--exchange',
                      default=CONSUMER_EXCHANGE,
                      dest='exchange',
                      help='RabbitMQ exchange (default: %s)' %
                      CONSUMER_EXCHANGE)
    parser.add_option('--key',
                      default=CONSUMER_KEY,
                      dest='key',
                      help='RabbitMQ key (default: %s)' % CONSUMER_KEY)
    parser.add_option('--callback',
                      default=None,
                      dest='callback',
                      help='Callback function to consume messages')
    parser.add_option('--test',
                      action='store_true',
                      default=False,
                      dest='test',
                      help='Produce a dummy message for testing')
    opts, args = parser.parse_args()

    DEBUG = False
    if opts.verbose:
        DEBUG = True
    logging.basicConfig(
        format='%(asctime)s [%(levelname)s] %(name)s %(message)s',
        datefmt='%Y-%m-%d %H:%M:%S',
        level=logging.DEBUG if DEBUG else logging.INFO)
    logger = logging.getLogger('dispatcher')

    host = 'amqp://%s:%s@%s:%s' % (opts.user, opts.password, opts.host,
                                   opts.port)
    queue = opts.queue
    key = opts.key
    exchange = opts.exchange

    client = AMQPClient(hosts=[host])
    client.connect()

    if opts.test:
        client.exchange_declare(exchange=exchange, type='topic')
        client.basic_publish(exchange=exchange,
                             routing_key=key,
                             body=json.dumps({"test": "0123456789"}))
        client.close()
        sys.exit()

    callback = None
    if opts.callback:
        cb = opts.callback.rsplit('.', 1)
        if len(cb) == 2:
            __import__(cb[0])
            cb_module = sys.modules[cb[0]]
            callback = getattr(cb_module, cb[1])

    def handle_message(client, msg):
        logger.debug('%s', msg)
        if callback:
            callback(msg)
        client.basic_ack(msg)

    client.queue_declare(queue=queue)
    client.queue_bind(queue=queue, exchange=exchange, routing_key=key)

    client.basic_consume(queue=queue, callback=handle_message)

    try:
        while True:
            client.basic_wait()
    except KeyboardInterrupt:
        pass
    finally:
        client.close()
示例#6
0
class Dispatcher:
    debug = False

    def __init__(self, debug=False):
        self.debug = debug
        self._init()

    def wait(self):
        log.info("Waiting for messages..")
        timeout = DISPATCHER_RECONNECT_TIMEOUT
        while True:
            try:
                # Close the Django DB connection before processing
                # every incoming message. This plays nicely with
                # DB connection pooling, if enabled and allows
                # the dispatcher to recover from broken connections
                # gracefully.
                close_connection()
                msg = self.client.basic_wait(timeout=timeout)
                if not msg:
                    log.warning("Idle connection for %d seconds. Will connect"
                                " to a different host. Verify that"
                                " snf-ganeti-eventd is running!!", timeout)
                    self.client.reconnect(timeout=1)
            except AMQPConnectionError as e:
                log.error("AMQP connection failed: %s" % e)
                log.warning("Sleeping for %d seconds before retrying to "
                            "connect to an AMQP broker" %
                            DISPATCHER_FAILED_CONNECTION_WAIT)
                time.sleep(DISPATCHER_FAILED_CONNECTION_WAIT)
            except select.error as e:
                if e[0] != errno.EINTR:
                    log.exception("Caught unexpected exception: %s", e)
                    log.warning("Sleeping for %d seconds before retrying to "
                                "connect to an AMQP broker" %
                                DISPATCHER_FAILED_CONNECTION_WAIT)
                    time.sleep(DISPATCHER_FAILED_CONNECTION_WAIT)
                else:
                    break
            except (SystemExit, KeyboardInterrupt):
                break
            except Exception as e:
                log.exception("Caught unexpected exception: %s", e)
                log.warning("Sleeping for %d seconds before retrying to "
                            "connect to an AMQP broker" %
                            DISPATCHER_FAILED_CONNECTION_WAIT)
                time.sleep(DISPATCHER_FAILED_CONNECTION_WAIT)

        log.info("Clean up AMQP connection before exit")
        self.client.basic_cancel(timeout=1)
        self.client.close(timeout=1)

    def _init(self):
        log.info("Initializing")

        # Set confirm buffer to 1 for heartbeat messages
        self.client = AMQPClient(logger=log_amqp, confirm_buffer=1)
        # Connect to AMQP host
        self.client.connect()

        # Declare queues and exchanges
        exchange = settings.EXCHANGE_GANETI
        exchange_dl = queues.convert_exchange_to_dead(exchange)
        self.client.exchange_declare(exchange=exchange,
                                     type="topic")
        self.client.exchange_declare(exchange=exchange_dl,
                                     type="topic")
        for queue in queues.QUEUES:
            # Queues are mirrored to all RabbitMQ brokers
            self.client.queue_declare(queue=queue, mirrored=True,
                                      dead_letter_exchange=exchange_dl)
            # Declare the corresponding dead-letter queue
            queue_dl = queues.convert_queue_to_dead(queue)
            self.client.queue_declare(queue=queue_dl, mirrored=True)

        # Bind queues to handler methods
        for binding in queues.BINDINGS:
            try:
                callback = getattr(callbacks, binding[3])
            except AttributeError:
                log.error("Cannot find callback %s", binding[3])
                raise SystemExit(1)
            queue = binding[0]
            exchange = binding[1]
            routing_key = binding[2]

            self.client.queue_bind(queue=queue, exchange=exchange,
                                   routing_key=routing_key)

            self.client.basic_consume(queue=binding[0],
                                      callback=callback,
                                      prefetch_count=5)

            queue_dl = queues.convert_queue_to_dead(queue)
            exchange_dl = queues.convert_exchange_to_dead(exchange)
            # Bind the corresponding dead-letter queue
            self.client.queue_bind(queue=queue_dl,
                                   exchange=exchange_dl,
                                   routing_key=routing_key)

            log.debug("Binding %s(%s) to queue %s with handler %s",
                      exchange, routing_key, queue, binding[3])

        # Declare the queue that will be used for receiving requests, e.g. a
        # status check request
        hostname, pid = get_hostname(), os.getpid()
        queue = queues.get_dispatcher_request_queue(hostname, pid)
        self.client.queue_declare(queue=queue, mirrored=True,
                                  ttl=REQUEST_QUEUE_TTL)
        self.client.basic_consume(queue=queue, callback=handle_request)
        log.debug("Binding %s(%s) to queue %s with handler 'hadle_request'",
                  exchange, routing_key, queue)