diff options
author | ISHIDA Wataru <ishida.wataru@lab.ntt.co.jp> | 2014-03-13 14:13:16 +0000 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2014-03-25 21:38:34 +0900 |
commit | 80ff7368fe274812e432d92521464d697f66b178 (patch) | |
tree | f783a40c0d97bf9213a71eefa4921fc09b156a06 | |
parent | 6212f37e2e373d04e7ab6f5c218a27ffcfd5fc50 (diff) |
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>
-rw-r--r-- | ryu/base/app_manager.py | 32 | ||||
-rw-r--r-- | ryu/controller/controller.py | 3 | ||||
-rw-r--r-- | ryu/controller/handler.py | 43 |
3 files changed, 49 insertions, 29 deletions
diff --git a/ryu/base/app_manager.py b/ryu/base/app_manager.py index 669e58bb..6b8708b0 100644 --- a/ryu/base/app_manager.py +++ b/ryu/base/app_manager.py @@ -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 - - # 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) + 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) + + # 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): diff --git a/ryu/controller/controller.py b/ryu/controller/controller.py index 93d2b33b..db5e54a4 100644 --- a/ryu/controller/controller.py +++ b/ryu/controller/controller.py @@ -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) diff --git a/ryu/controller/handler.py b/ryu/controller/handler.py index 43f07d1a..bb05726a 100644 --- a/ryu/controller/handler.py +++ b/ryu/controller/handler.py @@ -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 |