6a934060f0
Instead of spawning our own threads and relying on the oslo.messaging executor blocking, lets just use oslo.messaging's internal threading capabilities. This converts rpc.Connection to rpc.MessagingService, which is an oslo.service-based service and sets up messaging to managed there instead. Closes-bug: #1583330 Change-Id: I9f5a15f1c5dff7e90761887c519a15888096636b
154 lines
5.2 KiB
Python
154 lines
5.2 KiB
Python
# Copyright 2015 Akanda, Inc
|
|
#
|
|
# Author: Akanda, Inc
|
|
#
|
|
# 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.
|
|
|
|
from six.moves.urllib import parse as urlparse
|
|
|
|
from oslo_log import log as logging
|
|
from oslo_config import cfg
|
|
from oslo_service import service
|
|
import oslo_messaging
|
|
|
|
from astara.common.i18n import _LW
|
|
|
|
LOG = logging.getLogger(__name__)
|
|
|
|
|
|
def _deprecated_amqp_url():
|
|
"""Allow for deprecating amqp_url setting over time.
|
|
This warns and attempts to translate an amqp_url to something
|
|
oslo_messaging can use to load a driver.
|
|
"""
|
|
url = cfg.CONF.amqp_url
|
|
if not url:
|
|
return
|
|
LOG.warning(_LW(
|
|
'Use of amqp_url is deprecated. Please instead use options defined in '
|
|
'oslo_messaging_rabbit to declare your AMQP connection.'))
|
|
url = urlparse.urlsplit(url)
|
|
if url.scheme == 'amqp':
|
|
scheme = 'rabbit'
|
|
else:
|
|
scheme = url.scheme
|
|
port = str(url.port or 5672)
|
|
netloc = url.netloc
|
|
if netloc.endswith(':'):
|
|
netloc = netloc[:-1]
|
|
out = urlparse.urlunsplit((
|
|
scheme,
|
|
'%s:%s' % (netloc, port),
|
|
url.path,
|
|
'', ''
|
|
))
|
|
return out
|
|
|
|
|
|
def get_transport():
|
|
url = _deprecated_amqp_url()
|
|
return oslo_messaging.get_transport(conf=cfg.CONF, url=url)
|
|
|
|
|
|
def get_server(target, endpoints):
|
|
return oslo_messaging.get_rpc_server(
|
|
transport=get_transport(),
|
|
target=target,
|
|
endpoints=endpoints,
|
|
)
|
|
|
|
|
|
def get_target(topic, fanout=True, exchange=None, version=None, server=None):
|
|
return oslo_messaging.Target(
|
|
topic=topic, fanout=fanout, exchange=exchange, version=version,
|
|
server=server)
|
|
|
|
|
|
def get_rpc_client(topic, exchange=None, version='1.0'):
|
|
"""Creates an RPC client to be used to request methods be
|
|
executed on remote RPC servers
|
|
"""
|
|
target = get_target(topic=topic, exchange=exchange,
|
|
version=version, fanout=False)
|
|
return oslo_messaging.rpc.client.RPCClient(
|
|
get_transport(), target
|
|
)
|
|
|
|
|
|
def get_rpc_notifier(topic='notifications'):
|
|
return oslo_messaging.notify.Notifier(
|
|
transport=get_transport(),
|
|
# TODO(adam_g): driver should be specified in oslo.messaging's cfg
|
|
driver='messaging',
|
|
topic=topic,
|
|
)
|
|
|
|
|
|
class MessagingService(service.Service):
|
|
"""Used to create objects that can manage multiple RPC connections"""
|
|
def __init__(self):
|
|
super(MessagingService, self).__init__()
|
|
self._servers = set()
|
|
|
|
def _add_server(self, server):
|
|
self._servers.add(server)
|
|
|
|
def create_rpc_consumer(self, topic, endpoints):
|
|
"""Creates an RPC server for this host that will execute RPCs requested
|
|
by clients. Adds the resulting consumer to the pool of messaging
|
|
servers.
|
|
|
|
:param topic: Topic on which to listen for RPC requests
|
|
:param endpoints: List of endpoint objects that define methods that
|
|
the server will execute.
|
|
"""
|
|
target = get_target(topic=topic, fanout=True, server=cfg.CONF.host)
|
|
server = get_server(target, endpoints)
|
|
LOG.debug('Created RPC server on topic %s', topic)
|
|
self._add_server(server)
|
|
|
|
def create_notification_listener(self, endpoints, exchange=None,
|
|
topic='notifications'):
|
|
"""Creates an oslo.messaging notification listener associated with
|
|
provided endpoints. Adds the resulting listener to the pool of
|
|
messaging servers.
|
|
|
|
:param endpoints: list of endpoint objects that define methods for
|
|
processing prioritized notifications
|
|
:param exchange: Optional control exchange to listen on. If not
|
|
specified, oslo_messaging defaults to 'openstack'
|
|
:param topic: Topic on which to listen for notification events
|
|
"""
|
|
transport = get_transport()
|
|
target = get_target(topic=topic, fanout=False,
|
|
exchange=exchange)
|
|
pool = 'astara.' + topic + '.' + cfg.CONF.host
|
|
server = oslo_messaging.get_notification_listener(
|
|
transport, [target], endpoints, pool=pool, executor='threading')
|
|
LOG.debug(
|
|
'Created RPC notification listener on topic:%s/exchange:%s.',
|
|
topic, exchange)
|
|
self._add_server(server)
|
|
|
|
def start(self):
|
|
LOG.info('Astara notification listener service starting...')
|
|
super(MessagingService, self).start()
|
|
[s.start() for s in self._servers]
|
|
LOG.info('Astara notification listener service started.')
|
|
|
|
def stop(self):
|
|
LOG.info('Astara notification listener service stopping...')
|
|
super(MessagingService, self).stop()
|
|
[s.wait() for s in self._servers]
|
|
LOG.info('Astara notification listener service stopped.')
|