enable multistage @set_ev_cls or @set_ev_handler

Signed-off-by: ISHIDA Wataru <ishida.wataru@lab.ntt.co.jp>
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
This commit is contained in:
ISHIDA Wataru 2014-03-13 14:13:16 +00:00 committed by FUJITA Tomonori
parent 6212f37e2e
commit 80ff7368fe
3 changed files with 48 additions and 28 deletions

View File

@ -163,8 +163,9 @@ class RyuApp(object):
if state is None:
return handlers
dispatchers = lambda x: x.callers[ev.__class__].dispatchers
return [handler for handler in handlers
if not handler.dispatchers or state in handler.dispatchers]
if not dispatchers(handler) or state in dispatchers(handler)]
def get_observers(self, ev, state):
observers = []
@ -320,20 +321,23 @@ class AppManager(object):
def _update_bricks(self):
for i in SERVICE_BRICKS.values():
for _k, m in inspect.getmembers(i, inspect.ismethod):
if not hasattr(m, 'observer'):
if not hasattr(m, 'callers'):
continue
for e in m.callers.values():
if not e.ev_source:
continue
# name is module name of ev_cls
name = e.ev_source.split('.')[-1]
if name in SERVICE_BRICKS:
brick = SERVICE_BRICKS[name]
brick.register_observer(
e.ev_cls, i.name, e.dispatchers)
# name is module name of ev_cls
name = m.observer.split('.')[-1]
if name in SERVICE_BRICKS:
brick = SERVICE_BRICKS[name]
brick.register_observer(m.ev_cls, i.name, m.dispatchers)
# allow RyuApp and Event class are in different module
for brick in SERVICE_BRICKS.itervalues():
if m.ev_cls in brick._EVENTS:
brick.register_observer(m.ev_cls, i.name,
m.dispatchers)
# allow RyuApp and Event class are in different module
for brick in SERVICE_BRICKS.itervalues():
if e.ev_cls in brick._EVENTS:
brick.register_observer(e.ev_cls, i.name,
e.dispatchers)
@staticmethod
def _report_brick(name, app):

View File

@ -150,9 +150,10 @@ class Datapath(ofproto_protocol.ProtocolDesc):
ev = ofp_event.ofp_msg_to_ev(msg)
self.ofp_brick.send_event_to_observers(ev, self.state)
dispatchers = lambda x: x.callers[ev.__class__].dispatchers
handlers = [handler for handler in
self.ofp_brick.get_handlers(ev) if
self.state in handler.dispatchers]
self.state in dispatchers(handler)]
for handler in handlers:
handler(ev)

View File

@ -17,6 +17,7 @@
import inspect
import logging
import sys
from collections import namedtuple
LOG = logging.getLogger('ryu.controller.handler')
@ -26,21 +27,28 @@ CONFIG_DISPATCHER = "config"
MAIN_DISPATCHER = "main"
DEAD_DISPATCHER = "dead"
caller = namedtuple('caller', 'ev_cls dispatchers ev_source')
# should be named something like 'observe_event'
def set_ev_cls(ev_cls, dispatchers=None):
def _set_ev_cls_dec(handler):
handler.ev_cls = ev_cls
handler.dispatchers = _listify(dispatchers)
handler.observer = ev_cls.__module__
if 'callers' not in dir(handler):
handler.callers = {}
for e in _listify(ev_cls):
c = caller(e, _listify(dispatchers), e.__module__)
handler.callers[e] = c
return handler
return _set_ev_cls_dec
def set_ev_handler(ev_cls, dispatchers=None):
def _set_ev_cls_dec(handler):
handler.ev_cls = ev_cls
handler.dispatchers = _listify(dispatchers)
if 'callers' not in dir(handler):
handler.callers = {}
for e in _listify(ev_cls):
c = caller(e, _listify(dispatchers), None)
handler.callers[e] = c
return handler
return _set_ev_cls_dec
@ -49,6 +57,10 @@ def _is_ev_cls(meth):
return hasattr(meth, 'ev_cls')
def _has_caller(meth):
return hasattr(meth, 'callers')
def _listify(may_list):
if may_list is None:
may_list = []
@ -60,20 +72,23 @@ def _listify(may_list):
def register_instance(i):
for _k, m in inspect.getmembers(i, inspect.ismethod):
# LOG.debug('instance %s k %s m %s', i, _k, m)
if _is_ev_cls(m):
i.register_handler(m.ev_cls, m)
if _has_caller(m):
for c in m.callers.values():
i.register_handler(c.ev_cls, m)
def get_dependent_services(cls):
services = []
for _k, m in inspect.getmembers(cls, inspect.ismethod):
if _is_ev_cls(m):
service = getattr(sys.modules[m.ev_cls.__module__],
'_SERVICE_NAME', None)
if service:
# avoid cls that registers the own events (like ofp_handler)
if cls.__module__ != service:
services.append(service)
if _has_caller(m):
for c in m.callers.values():
service = getattr(sys.modules[c.ev_cls.__module__],
'_SERVICE_NAME', None)
if service:
# avoid cls that registers the own events (like
# ofp_handler)
if cls.__module__ != service:
services.append(service)
services = list(set(services))
return services