Implement _broadcast_dispatcher in EngineService.

This commit is contained in:
yanyanhu 2015-01-06 01:17:28 -05:00
parent 2c82c8e07f
commit 6a7fe4ab41

View File

@ -13,7 +13,6 @@
import functools import functools
import eventlet
from oslo.config import cfg from oslo.config import cfg
from oslo import messaging from oslo import messaging
from oslo.utils import uuidutils from oslo.utils import uuidutils
@ -57,16 +56,18 @@ class Dispatcher(service.Service):
OPERATIONS = (NEW_ACTION, CANCEL_ACTION, SEND, STOP) = ( OPERATIONS = (NEW_ACTION, CANCEL_ACTION, SEND, STOP) = (
'new_action', 'cancel_action', 'send', 'stop') 'new_action', 'cancel_action', 'send', 'stop')
def __init__(self, host, engine_id, thread_group_mgr): def __init__(self, engine_id, topic, version, thread_group_mgr):
super(Dispatcher, self).__init__() super(Dispatcher, self).__init__()
self.TG = thread_group_mgr self.TG = thread_group_mgr
self.engine_id = engine_id self.engine_id = engine_id
self.host = host self.topic = topic
self.version = version
def start(self): def start(self):
super(Dispatcher, self).start() super(Dispatcher, self).start()
self.target = messaging.Target( self.target = messaging.Target(server=self.engine_id,
server=self.host, topic=self.engine_id) topic=self.topic,
version=self.version)
server = rpc_messaging.get_rpc_server(self.target, self) server = rpc_messaging.get_rpc_server(self.target, self)
server.start() server.start()
@ -126,6 +127,7 @@ class EngineService(service.Service):
# is ready # is ready
self.host = host self.host = host
self.topic = topic self.topic = topic
self.dispatcher_topic = self.topic + '-dispatcher'
# The following are initialized here, but assigned in start() which # The following are initialized here, but assigned in start() which
# happens after the fork when spawning multiple worker processes # happens after the fork when spawning multiple worker processes
@ -140,12 +142,15 @@ class EngineService(service.Service):
# TODO(Yanyan): create a dispatcher for this engine thread. # TODO(Yanyan): create a dispatcher for this engine thread.
# This dispatcher will run in a greenthread and it will not # This dispatcher will run in a greenthread and it will not
# stop until being notified or the engine is stopped. # stop until being notified or the engine is stopped.
self.dispatcher = Dispatcher(self.host, self.engine_id, self.TG) self.dispatcher = Dispatcher(self.engine_id,
self.dispatcher_topic,
self.RPC_API_VERSION,
self.TG)
LOG.debug("Starting dispatcher for engine %s" % self.engine_id) LOG.debug("Starting dispatcher for engine %s" % self.engine_id)
self.dispatcher.start() self.dispatcher.start()
target = messaging.Target( target = messaging.Target(version=self.RPC_API_VERSION,
version=self.RPC_API_VERSION, server=self.host, server=self.host,
topic=self.topic) topic=self.topic)
self.target = target self.target = target
server = rpc_messaging.get_rpc_server(target, self) server = rpc_messaging.get_rpc_server(target, self)
@ -165,7 +170,7 @@ class EngineService(service.Service):
pass pass
# Notify dispatcher to stop all action threads it started. # Notify dispatcher to stop all action threads it started.
res = self._notify_dispatcher(context, self._notify_dispatcher(context,
self.engine_id, self.engine_id,
self.dispatcher.STOP) self.dispatcher.STOP)
@ -296,11 +301,10 @@ class EngineService(service.Service):
# Build an Action for Cluster creating # Build an Action for Cluster creating
action = actions.Action(context, cluster, 'CLUSTER_CREATE', **kwargs) action = actions.Action(context, cluster, 'CLUSTER_CREATE', **kwargs)
action.store() action.store()
# Notify Dispatcher that a new action has been ready. # Notify Dispatchers that a new action has been ready.
# TODO(Yanyan): We should broadcast this new action self._broadcast_dispatcher(context,
# coming to all active Dispatchers. self.engine_id,
res = self._notify_dispatcher( self.dispatcher.NEW_ACTION,
context, self.engine_id, self.dispatcher.NEW_ACTION,
action_id=action.id) action_id=action.id)
return cluster.id return cluster.id
@ -333,8 +337,9 @@ class EngineService(service.Service):
} }
action = actions.Action(context, cluster, 'CLUSTER_UPDATE', **kwargs) action = actions.Action(context, cluster, 'CLUSTER_UPDATE', **kwargs)
res = self._notify_dispatcher( self._broadcast_dispatcher(context,
context, self.engine_id, self.dispatcher.NEW_ACTION, self.engine_id,
self.dispatcher.NEW_ACTION,
action_id=action.id) action_id=action.id)
return cluster.id return cluster.id
@ -351,11 +356,11 @@ class EngineService(service.Service):
db_cluster = self._get_cluster(context, cluster_identity) db_cluster = self._get_cluster(context, cluster_identity)
LOG.info(_LI('Deleting cluster %s'), db_cluster.name) LOG.info(_LI('Deleting cluster %s'), db_cluster.name)
# This is an operation on a cluster, so we try to acquire ClusterLock
cluster = clusters.Cluster.load(context, cluster=db_cluster) cluster = clusters.Cluster.load(context, cluster=db_cluster)
action = actions.Action(context, cluster, 'CLUSTER_DELETE') action = actions.Action(context, cluster, 'CLUSTER_DELETE')
res = self._notify_dispatcher( res = self._broadcast_dispatcher(context,
context, self.engine_id, self.dispatcher.NEW_ACTION, self.engine_id,
self.dispatcher.NEW_ACTION,
action_id=action.id) action_id=action.id)
return res return res
@ -363,16 +368,23 @@ class EngineService(service.Service):
def _notify_dispatcher(self, cnxt, engine_id, call, *args, **kwargs): def _notify_dispatcher(self, cnxt, engine_id, call, *args, **kwargs):
'''Send notification to specific dispatcher''' '''Send notification to specific dispatcher'''
timeout = cfg.CONF.engine_life_check_timeout timeout = cfg.CONF.engine_life_check_timeout
self.cctxt = self._client.prepare( self.cctxt = self._client.prepare(version=self.RPC_API_VERSION,
version='1.0',
timeout=timeout, timeout=timeout,
topic=engine_id) topic=self.dispatcher_topic,
server=engine_id)
try: try:
self.cctxt.call(cnxt, call, *args, **kwargs) self.cctxt.call(cnxt, call, *args, **kwargs)
except messaging.MessagingTimeout: except messaging.MessagingTimeout:
return False return False
def _broadcast_dispatcher(self, cnxt, engine_id, call, *args, def _broadcast_dispatcher(self, cnxt, call, *args, **kwargs):
**kwargs): '''Broadcast notification to all active dispatchers'''
'''Broadcast the notification to all active dispatchers''' timeout = cfg.CONF.engine_life_check_timeout
raise NotImplementedError self.cctxt = self._client.prepare(version=self.RPC_API_VERSION,
timeout=timeout,
topic=self.dispatcher_topic,
fanout=True)
try:
self.cctxt.call(cnxt, call, *args, **kwargs)
except messaging.MessagingTimeout:
return False