summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorISHIDA Wataru <ishida.wataru@lab.ntt.co.jp>2014-03-13 14:13:16 +0000
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2014-03-25 21:38:34 +0900
commit80ff7368fe274812e432d92521464d697f66b178 (patch)
treef783a40c0d97bf9213a71eefa4921fc09b156a06
parent6212f37e2e373d04e7ab6f5c218a27ffcfd5fc50 (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.py32
-rw-r--r--ryu/controller/controller.py3
-rw-r--r--ryu/controller/handler.py43
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