
* H305 imports not grouped correctly * H307 like imports should be grouped together Change-Id: If1dd9c89f65ede6959865a885777cb08c263eca0
115 lines
4.3 KiB
Python
115 lines
4.3 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
# Copyright (C) 2014 Yahoo! Inc. All Rights Reserved.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License. You may obtain
|
|
# a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
|
|
import logging
|
|
import socket
|
|
import threading
|
|
|
|
import kombu
|
|
import six
|
|
|
|
LOG = logging.getLogger(__name__)
|
|
|
|
# NOTE(skudriashev): A timeout of 1 is often used in environments where
|
|
# the socket can get "stuck", and is a best practice for Kombu consumers.
|
|
DRAIN_EVENTS_PERIOD = 1
|
|
|
|
|
|
class Proxy(object):
|
|
"""A proxy processes messages from/to the named exchange."""
|
|
|
|
def __init__(self, topic, exchange_name, on_message, on_wait=None,
|
|
**kwargs):
|
|
self._topic = topic
|
|
self._exchange_name = exchange_name
|
|
self._on_message = on_message
|
|
self._on_wait = on_wait
|
|
self._running = threading.Event()
|
|
self._url = kwargs.get('url')
|
|
self._transport = kwargs.get('transport')
|
|
self._transport_opts = kwargs.get('transport_options')
|
|
|
|
self._drain_events_timeout = DRAIN_EVENTS_PERIOD
|
|
if self._transport == 'memory' and self._transport_opts:
|
|
polling_interval = self._transport_opts.get('polling_interval')
|
|
if polling_interval:
|
|
self._drain_events_timeout = polling_interval
|
|
|
|
# create connection
|
|
self._conn = kombu.Connection(self._url, transport=self._transport,
|
|
transport_options=self._transport_opts)
|
|
|
|
# create exchange
|
|
self._exchange = kombu.Exchange(name=self._exchange_name,
|
|
durable=False,
|
|
auto_delete=True)
|
|
|
|
@property
|
|
def is_running(self):
|
|
"""Return whether the proxy is running."""
|
|
return self._running.is_set()
|
|
|
|
def _make_queue(self, name, exchange, **kwargs):
|
|
"""Make named queue for the given exchange."""
|
|
return kombu.Queue(name="%s_%s" % (self._exchange_name, name),
|
|
exchange=exchange,
|
|
routing_key=name,
|
|
durable=False,
|
|
auto_delete=True,
|
|
**kwargs)
|
|
|
|
def publish(self, msg, routing_key, **kwargs):
|
|
"""Publish message to the named exchange with given routing key."""
|
|
LOG.debug("Sending %s", msg)
|
|
if isinstance(routing_key, six.string_types):
|
|
routing_keys = [routing_key]
|
|
else:
|
|
routing_keys = routing_key
|
|
with kombu.producers[self._conn].acquire(block=True) as producer:
|
|
for routing_key in routing_keys:
|
|
queue = self._make_queue(routing_key, self._exchange)
|
|
producer.publish(body=msg.to_dict(),
|
|
routing_key=routing_key,
|
|
exchange=self._exchange,
|
|
declare=[queue],
|
|
type=msg.TYPE,
|
|
**kwargs)
|
|
|
|
def start(self):
|
|
"""Start proxy."""
|
|
LOG.info("Starting to consume from the '%s' exchange.",
|
|
self._exchange_name)
|
|
with kombu.connections[self._conn].acquire(block=True) as conn:
|
|
queue = self._make_queue(self._topic, self._exchange, channel=conn)
|
|
with conn.Consumer(queues=queue,
|
|
callbacks=[self._on_message]):
|
|
self._running.set()
|
|
while self.is_running:
|
|
try:
|
|
conn.drain_events(timeout=self._drain_events_timeout)
|
|
except socket.timeout:
|
|
pass
|
|
if self._on_wait is not None:
|
|
self._on_wait()
|
|
|
|
def wait(self):
|
|
"""Wait until proxy is started."""
|
|
self._running.wait()
|
|
|
|
def stop(self):
|
|
"""Stop proxy."""
|
|
self._running.clear()
|