class ZmqSocket(object): SERIALIZERS = { 'json': json_serializer.JSONSerializer(), 'msgpack': msgpack_serializer.MessagePackSerializer() } def __init__(self, conf, context, socket_type, immediate=True, high_watermark=0): self.conf = conf self.context = context self.socket_type = socket_type self.handle = context.socket(socket_type) self.handle.set_hwm(high_watermark) self.close_linger = -1 if self.conf.rpc_cast_timeout > 0: self.close_linger = self.conf.rpc_cast_timeout * 1000 self.handle.setsockopt(zmq.LINGER, self.close_linger) # Put messages to only connected queues self.handle.setsockopt(zmq.IMMEDIATE, 1 if immediate else 0) self.handle.identity = six.b(str(uuid.uuid4())) self.connections = set() def _get_serializer(self, serialization): serializer = self.SERIALIZERS.get(serialization, None) if serializer is None: raise NotImplementedError( "Serialization '{}' is not supported".format(serialization) ) return serializer def type_name(self): return zmq_names.socket_type_str(self.socket_type) def connections_count(self): return len(self.connections) def connect(self, address): if address not in self.connections: self.handle.connect(address) self.connections.add(address) def setsockopt(self, *args, **kwargs): self.handle.setsockopt(*args, **kwargs) def setsockopt_string(self, *args, **kwargs): self.handle.setsockopt_string(*args, **kwargs) def send(self, *args, **kwargs): self.handle.send(*args, **kwargs) def send_string(self, *args, **kwargs): self.handle.send_string(*args, **kwargs) def send_json(self, *args, **kwargs): self.handle.send_json(*args, **kwargs) def send_pyobj(self, *args, **kwargs): self.handle.send_pyobj(*args, **kwargs) def send_multipart(self, *args, **kwargs): self.handle.send_multipart(*args, **kwargs) def send_dumped(self, obj, *args, **kwargs): serialization = kwargs.pop('serialization', self.conf.rpc_zmq_serialization) serializer = self._get_serializer(serialization) s = serializer.dump_as_bytes(obj) self.handle.send(s, *args, **kwargs) def recv(self, *args, **kwargs): return self.handle.recv(*args, **kwargs) def recv_string(self, *args, **kwargs): return self.handle.recv_string(*args, **kwargs) def recv_json(self, *args, **kwargs): return self.handle.recv_json(*args, **kwargs) def recv_pyobj(self, *args, **kwargs): return self.handle.recv_pyobj(*args, **kwargs) def recv_multipart(self, *args, **kwargs): return self.handle.recv_multipart(*args, **kwargs) def recv_loaded(self, *args, **kwargs): serialization = kwargs.pop('serialization', self.conf.rpc_zmq_serialization) serializer = self._get_serializer(serialization) s = self.handle.recv(*args, **kwargs) obj = serializer.load_from_bytes(s) return obj def close(self, *args, **kwargs): self.handle.close(*args, **kwargs) def connect_to_address(self, address): if address in self.connections: return stype = zmq_names.socket_type_str(self.socket_type) try: LOG.info(_LI("Connecting %(stype)s id %(id)s to %(address)s"), {"stype": stype, "id": self.handle.identity, "address": address}) self.connect(address) except zmq.ZMQError as e: errmsg = _LE("Failed connecting %(stype)s to %(address)s: %(e)s") \ % {"stype": stype, "address": address, "e": e} LOG.error(_LE("Failed connecting %(stype)s to %(address)s: %(e)s"), {"stype": stype, "address": address, "e": e}) raise rpc_common.RPCException(errmsg) def connect_to_host(self, host): address = zmq_address.get_tcp_direct_address( host.decode('utf-8') if six.PY3 and isinstance(host, six.binary_type) else host ) self.connect_to_address(address)
class ZmqSocket(object): SERIALIZERS = { 'json': json_serializer.JSONSerializer(), 'msgpack': msgpack_serializer.MessagePackSerializer() } def __init__(self, conf, context, socket_type, immediate, high_watermark=0, identity=None): self.conf = conf self.context = context self.socket_type = socket_type self.handle = context.socket(socket_type) self.handle.set_hwm(high_watermark) # Set linger period linger = -1 if self.conf.oslo_messaging_zmq.zmq_linger >= 0: # Convert seconds to milliseconds linger = self.conf.oslo_messaging_zmq.zmq_linger * 1000 self.handle.setsockopt(zmq.LINGER, linger) # Put messages to only connected queues self.handle.setsockopt(zmq.IMMEDIATE, 1 if immediate else 0) # Setup timeout on socket sending if hasattr(self.conf, 'rpc_response_timeout'): self.handle.setsockopt(zmq.SNDTIMEO, self.conf.rpc_response_timeout * 1000) # Configure TCP keep alive keepalive = self.conf.oslo_messaging_zmq.zmq_tcp_keepalive if keepalive < 0: keepalive = -1 elif keepalive > 0: keepalive = 1 self.handle.setsockopt(zmq.TCP_KEEPALIVE, keepalive) keepalive_idle = self.conf.oslo_messaging_zmq.zmq_tcp_keepalive_idle if keepalive_idle <= 0: keepalive_idle = -1 self.handle.setsockopt(zmq.TCP_KEEPALIVE_IDLE, keepalive_idle) keepalive_cnt = self.conf.oslo_messaging_zmq.zmq_tcp_keepalive_cnt if keepalive_cnt <= 0: keepalive_cnt = -1 self.handle.setsockopt(zmq.TCP_KEEPALIVE_CNT, keepalive_cnt) keepalive_intvl = self.conf.oslo_messaging_zmq.zmq_tcp_keepalive_intvl if keepalive_intvl <= 0: keepalive_intvl = -1 self.handle.setsockopt(zmq.TCP_KEEPALIVE_INTVL, keepalive_intvl) self.handle.identity = \ six.b(str(uuid.uuid4())) if identity is None else identity self.connections = set() def _get_serializer(self, serialization): serializer = self.SERIALIZERS.get(serialization, None) if serializer is None: raise NotImplementedError( "Serialization '{}' is not supported".format(serialization)) return serializer def type_name(self): return zmq_names.socket_type_str(self.socket_type) def connections_count(self): return len(self.connections) def connect(self, address): if address not in self.connections: self.handle.connect(address) self.connections.add(address) def setsockopt(self, *args, **kwargs): self.handle.setsockopt(*args, **kwargs) def setsockopt_string(self, *args, **kwargs): self.handle.setsockopt_string(*args, **kwargs) def getsockopt(self, *args, **kwargs): return self.handle.getsockopt(*args, **kwargs) def getsockopt_string(self, *args, **kwargs): return self.handle.getsockopt_string(*args, **kwargs) def send(self, *args, **kwargs): self.handle.send(*args, **kwargs) def send_string(self, u, *args, **kwargs): # NOTE(ozamiatin): Not using send_string until # eventlet zmq support this convenience method # in thread-safe manner encoding = kwargs.pop('encoding', 'utf-8') s = u.encode(encoding) if isinstance(u, six.text_type) else u self.handle.send(s, *args, **kwargs) def send_json(self, *args, **kwargs): self.handle.send_json(*args, **kwargs) def send_pyobj(self, *args, **kwargs): self.handle.send_pyobj(*args, **kwargs) def send_multipart(self, *args, **kwargs): self.handle.send_multipart(*args, **kwargs) def send_dumped(self, obj, *args, **kwargs): serialization = kwargs.pop( 'serialization', self.conf.oslo_messaging_zmq.rpc_zmq_serialization) serializer = self._get_serializer(serialization) s = serializer.dump_as_bytes(obj) self.handle.send(s, *args, **kwargs) def recv(self, *args, **kwargs): return self.handle.recv(*args, **kwargs) def recv_string(self, *args, **kwargs): # NOTE(ozamiatin): Not using recv_string until # eventlet zmq support this convenience method # in thread-safe manner encoding = kwargs.pop('encoding', 'utf-8') s = self.handle.recv(*args, **kwargs) u = s.decode(encoding) if isinstance(s, six.binary_type) else s return u def recv_json(self, *args, **kwargs): return self.handle.recv_json(*args, **kwargs) def recv_pyobj(self, *args, **kwargs): return self.handle.recv_pyobj(*args, **kwargs) def recv_multipart(self, *args, **kwargs): return self.handle.recv_multipart(*args, **kwargs) def recv_loaded(self, *args, **kwargs): serialization = kwargs.pop( 'serialization', self.conf.oslo_messaging_zmq.rpc_zmq_serialization) serializer = self._get_serializer(serialization) s = self.handle.recv(*args, **kwargs) obj = serializer.load_from_bytes(s) return obj def close(self, *args, **kwargs): identity = self.handle.identity self.handle.close(*args, **kwargs) LOG.debug("Socket %s closed" % identity) def connect_to_address(self, address): if address in self.connections: return stype = zmq_names.socket_type_str(self.socket_type) sid = self.handle.identity try: LOG.debug("Connecting %(stype)s socket %(sid)s to %(address)s", { "stype": stype, "sid": sid, "address": address }) self.connect(address) except zmq.ZMQError as e: LOG.error( _LE("Failed connecting %(stype)s-%(sid)s to " "%(address)s: %(e)s"), { "stype": stype, "sid": sid, "address": address, "e": e }) raise rpc_common.RPCException( "Failed connecting %(stype)s-%(sid)s to %(address)s: %(e)s" % { "stype": stype, "sid": sid, "address": address, "e": e }) def connect_to_host(self, host): address = zmq_address.get_tcp_direct_address( host.decode('utf-8') if six.PY3 and isinstance(host, six.binary_type) else host) self.connect_to_address(address)
# 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 select import socket from oslo_serialization.serializer import json_serializer from oslo_serialization.serializer import msgpack_serializer from oslo_utils import timeutils from pika import exceptions as pika_exceptions import six PIKA_CONNECTIVITY_ERRORS = (pika_exceptions.AMQPConnectionError, pika_exceptions.ConnectionClosed, pika_exceptions.ChannelClosed, socket.timeout, select.error) EXCEPTIONS_MODULE = 'exceptions' if six.PY2 else 'builtins' INFINITE_STOP_WATCH = timeutils.StopWatch(duration=None).start() MESSAGE_SERIALIZERS = { 'application/json': json_serializer.JSONSerializer(), 'application/msgpack': msgpack_serializer.MessagePackSerializer() }