Short-circuit notifications when not enabled
In Mitaka oslo messaging introduced the transport_url specific for notifications under the oslo_messaging_notifications section, but some projects still use the default transport_url defined in the DEFAULT section. Use messaging notifications transport instead of default. This patch proposes short-circuiting notification methods as much as possible to optimize code execution when Karbor has no notification transport mechanism configured. The NOTIFIER only be inited only if notifications are actually enabled. Change-Id: Id9419ddd801bf9d8ac13c4a73a91e39fd763cb2b Closes-Bug: #1719786
This commit is contained in:
parent
3f3df9b761
commit
2f529a62bf
|
@ -26,13 +26,14 @@ __all__ = [
|
|||
from oslo_config import cfg
|
||||
import oslo_messaging as messaging
|
||||
from oslo_messaging.rpc import dispatcher
|
||||
from oslo_serialization import jsonutils
|
||||
|
||||
import karbor.context
|
||||
import karbor.exception
|
||||
from karbor import utils
|
||||
|
||||
CONF = cfg.CONF
|
||||
TRANSPORT = None
|
||||
NOTIFICATION_TRANSPORT = None
|
||||
NOTIFIER = None
|
||||
|
||||
ALLOWED_EXMODS = [
|
||||
|
@ -42,16 +43,24 @@ EXTRA_EXMODS = []
|
|||
|
||||
|
||||
def init(conf):
|
||||
if initialized():
|
||||
return
|
||||
|
||||
global TRANSPORT, NOTIFIER
|
||||
global TRANSPORT, NOTIFICATION_TRANSPORT, NOTIFIER
|
||||
exmods = get_allowed_exmods()
|
||||
TRANSPORT = messaging.get_rpc_transport(conf,
|
||||
allowed_remote_exmods=exmods)
|
||||
NOTIFICATION_TRANSPORT = messaging.get_notification_transport(
|
||||
conf,
|
||||
allowed_remote_exmods=exmods)
|
||||
|
||||
serializer = RequestContextSerializer(JsonPayloadSerializer())
|
||||
NOTIFIER = messaging.Notifier(TRANSPORT, serializer=serializer)
|
||||
# get_notification_transport has loaded oslo_messaging_notifications config
|
||||
# group, so we can now check if notifications are actually enabled.
|
||||
if utils.notifications_enabled(conf):
|
||||
json_serializer = messaging.JsonPayloadSerializer()
|
||||
serializer = RequestContextSerializer(json_serializer)
|
||||
NOTIFIER = messaging.Notifier(NOTIFICATION_TRANSPORT,
|
||||
serializer=serializer)
|
||||
else:
|
||||
NOTIFIER = utils.DO_NOTHING
|
||||
|
||||
|
||||
def initialized():
|
||||
|
@ -59,11 +68,12 @@ def initialized():
|
|||
|
||||
|
||||
def cleanup():
|
||||
global TRANSPORT, NOTIFIER
|
||||
global TRANSPORT, NOTIFICATION_TRANSPORT, NOTIFIER
|
||||
assert TRANSPORT is not None
|
||||
assert NOTIFIER is not None
|
||||
|
||||
TRANSPORT.cleanup()
|
||||
TRANSPORT = NOTIFIER = None
|
||||
NOTIFICATION_TRANSPORT.cleanup()
|
||||
TRANSPORT = NOTIFICATION_TRANSPORT = NOTIFIER = None
|
||||
|
||||
|
||||
def set_defaults(control_exchange):
|
||||
|
@ -82,12 +92,6 @@ def get_allowed_exmods():
|
|||
return ALLOWED_EXMODS + EXTRA_EXMODS
|
||||
|
||||
|
||||
class JsonPayloadSerializer(messaging.NoOpSerializer):
|
||||
@staticmethod
|
||||
def serialize_entity(context, entity):
|
||||
return jsonutils.to_primitive(entity, convert_instances=True)
|
||||
|
||||
|
||||
class RequestContextSerializer(messaging.Serializer):
|
||||
|
||||
def __init__(self, base):
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
# 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 mock
|
||||
|
||||
from oslo_config import cfg
|
||||
|
||||
from karbor import rpc
|
||||
from karbor.tests import base
|
||||
|
||||
|
||||
CONF = cfg.CONF
|
||||
|
||||
|
||||
class RPCAPITestCase(base.TestCase):
|
||||
"""Tests RPCAPI mixin aggregating stuff related to RPC compatibility."""
|
||||
|
||||
def setUp(self):
|
||||
super(RPCAPITestCase, self).setUp()
|
||||
|
||||
@mock.patch('oslo_messaging.JsonPayloadSerializer', wraps=True)
|
||||
def test_init_no_notifications(self, serializer_mock):
|
||||
"""Test short-circuiting notifications with default and noop driver."""
|
||||
driver = ['noop']
|
||||
self.override_config('driver', driver,
|
||||
group='oslo_messaging_notifications')
|
||||
rpc.init(CONF)
|
||||
self.assertEqual(rpc.utils.DO_NOTHING, rpc.NOTIFIER)
|
||||
serializer_mock.assert_not_called()
|
||||
|
||||
@mock.patch.object(rpc, 'messaging')
|
||||
def test_init_notifications(self, messaging_mock):
|
||||
self.override_config('driver', ['test'],
|
||||
group='oslo_messaging_notifications')
|
||||
rpc.init(CONF)
|
||||
self.assertTrue(messaging_mock.JsonPayloadSerializer.called)
|
||||
self.assertTrue(messaging_mock.Notifier.called)
|
||||
self.assertEqual(rpc.NOTIFIER, messaging_mock.Notifier.return_value)
|
|
@ -192,3 +192,24 @@ def tempdir(**kwargs):
|
|||
except OSError as e:
|
||||
LOG.debug('Could not remove tmpdir: %s',
|
||||
six.text_type(e))
|
||||
|
||||
|
||||
class DoNothing(str):
|
||||
"""Class that literally does nothing.
|
||||
|
||||
We inherit from str in case it's called with json.dumps.
|
||||
"""
|
||||
def __call__(self, *args, **kwargs):
|
||||
return self
|
||||
|
||||
def __getattr__(self, name):
|
||||
return self
|
||||
|
||||
|
||||
DO_NOTHING = DoNothing()
|
||||
|
||||
|
||||
def notifications_enabled(conf):
|
||||
"""Check if oslo notifications are enabled."""
|
||||
notifications_driver = set(conf.oslo_messaging_notifications.driver)
|
||||
return notifications_driver and notifications_driver != {'noop'}
|
||||
|
|
Loading…
Reference in New Issue