zun/zun/common/rpc.py
Hongbin Lu de82a5dc81 Reuse the RPC transport to create RPC client
In before, we created a PRC transport per RPC call. This causes
too many RPC connections as reported by the bug. This patch fixes
it by initialize the RPC transport at startup and reuse the RPC
transport for each API call.

Change-Id: I55e409e0b70024673bd25ab460c2a5bfecc717a5
Closes-Bug: #1785371
2018-08-05 20:40:03 +00:00

124 lines
3.4 KiB
Python

# Copyright 2014 Red Hat, 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.
__all__ = [
'init',
'set_defaults',
'add_extra_exmods',
'clear_extra_exmods',
'get_allowed_exmods',
'RequestContextSerializer',
'get_client',
]
import oslo_messaging as messaging
from oslo_serialization import jsonutils as json
from oslo_utils import importutils
from zun.common import context as zun_context
from zun.common import exception
profiler = importutils.try_import("osprofiler.profiler")
TRANSPORT = None
ALLOWED_EXMODS = [
exception.__name__,
]
EXTRA_EXMODS = []
def init(conf):
global TRANSPORT
exmods = get_allowed_exmods()
TRANSPORT = messaging.get_rpc_transport(
conf, allowed_remote_exmods=exmods)
def set_defaults(control_exchange):
messaging.set_transport_defaults(control_exchange)
def add_extra_exmods(*args):
EXTRA_EXMODS.extend(args)
def clear_extra_exmods():
del EXTRA_EXMODS[:]
def get_allowed_exmods():
return ALLOWED_EXMODS + EXTRA_EXMODS
class JsonPayloadSerializer(messaging.NoOpSerializer):
@staticmethod
def serialize_entity(context, entity):
return json.to_primitive(entity, convert_instances=True)
class RequestContextSerializer(messaging.Serializer):
def __init__(self, base):
self._base = base
def serialize_entity(self, context, entity):
if not self._base:
return entity
return self._base.serialize_entity(context, entity)
def deserialize_entity(self, context, entity):
if not self._base:
return entity
return self._base.deserialize_entity(context, entity)
def serialize_context(self, context):
return context.to_dict()
def deserialize_context(self, context):
return zun_context.RequestContext.from_dict(context)
class ProfilerRequestContextSerializer(RequestContextSerializer):
def serialize_context(self, context):
_context = super(ProfilerRequestContextSerializer,
self).serialize_context(context)
prof = profiler.get()
if prof:
trace_info = {
"hmac_key": prof.hmac_key,
"base_id": prof.get_base_id(),
"parent_id": prof.get_id()
}
_context.update({"trace_info": trace_info})
return _context
def deserialize_context(self, context):
trace_info = context.pop("trace_info", None)
if trace_info:
profiler.init(**trace_info)
return super(ProfilerRequestContextSerializer,
self).deserialize_context(context)
def get_client(target, serializer=None, timeout=None):
assert TRANSPORT is not None
return messaging.RPCClient(TRANSPORT,
target,
serializer=serializer,
timeout=timeout)