In order to complete implementation of the spec [2] and for optimal zmq-way patterns usage. By zmq-way meaning some relaxed guarantees on reliability, but high performance and scalability. PUSH/PULL for CASTs here gives us benefit of not having redundant backward tcp-connections which DEALER/ROUTER opens. Opposite to that there is another approach provided by spec [1]. This approach has strong gurantees on messages delivery based on acknowledgements and retries. Such approach has lower performance though. The general idea is to provide both approaches in the driver and switch between them in configuration. 1. https://review.openstack.org/#/c/171131/ 2. https://review.openstack.org/#/c/187338/ Change-Id: I32712f73e2ec4114406641de5aec3b12152ad58f
80 lines
2.8 KiB
Python
80 lines
2.8 KiB
Python
# Copyright 2015 Mirantis, 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.
|
|
|
|
import copy
|
|
import logging
|
|
|
|
from oslo_messaging._drivers import base
|
|
from oslo_messaging._drivers.zmq_driver.server.consumers\
|
|
import zmq_pull_consumer
|
|
from oslo_messaging._drivers.zmq_driver.server.consumers\
|
|
import zmq_router_consumer
|
|
from oslo_messaging._drivers.zmq_driver.server.consumers\
|
|
import zmq_sub_consumer
|
|
from oslo_messaging._drivers.zmq_driver import zmq_async
|
|
from oslo_messaging._i18n import _LI
|
|
|
|
LOG = logging.getLogger(__name__)
|
|
|
|
zmq = zmq_async.import_zmq()
|
|
|
|
|
|
class ZmqServer(base.Listener):
|
|
|
|
def __init__(self, driver, conf, matchmaker=None):
|
|
super(ZmqServer, self).__init__(driver)
|
|
self.matchmaker = matchmaker
|
|
self.poller = zmq_async.get_poller()
|
|
self.router_consumer = zmq_router_consumer.RouterConsumer(
|
|
conf, self.poller, self)
|
|
self.pull_consumer = zmq_pull_consumer.PullConsumer(
|
|
conf, self.poller, self)
|
|
self.sub_consumer = zmq_sub_consumer.SubConsumer(
|
|
conf, self.poller, self) if conf.use_pub_sub else None
|
|
self.notify_consumer = self.sub_consumer if conf.use_pub_sub \
|
|
else self.router_consumer
|
|
|
|
self.consumers = [self.router_consumer, self.pull_consumer]
|
|
if self.sub_consumer:
|
|
self.consumers.append(self.sub_consumer)
|
|
|
|
@base.batch_poll_helper
|
|
def poll(self, timeout=None):
|
|
message, socket = self.poller.poll(
|
|
timeout or self.conf.rpc_poll_timeout)
|
|
return message
|
|
|
|
def stop(self):
|
|
consumer = self.router_consumer
|
|
LOG.info(_LI("Stop server %(address)s:%(port)s"),
|
|
{'address': consumer.address, 'port': consumer.port})
|
|
|
|
def cleanup(self):
|
|
self.poller.close()
|
|
for consumer in self.consumers:
|
|
consumer.cleanup()
|
|
|
|
def listen(self, target):
|
|
self.router_consumer.listen(target)
|
|
self.pull_consumer.listen(target)
|
|
if self.sub_consumer:
|
|
self.sub_consumer.listen(target)
|
|
|
|
def listen_notification(self, targets_and_priorities):
|
|
consumer = self.notify_consumer
|
|
for target, priority in targets_and_priorities:
|
|
t = copy.deepcopy(target)
|
|
t.topic = target.topic + '.' + priority
|
|
consumer.listen(t)
|