summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rwxr-xr-xbin/ryu-manager15
-rw-r--r--ryu/base/app_manager.py97
2 files changed, 95 insertions, 17 deletions
diff --git a/bin/ryu-manager b/bin/ryu-manager
index cb57e623..a6944e2e 100755
--- a/bin/ryu-manager
+++ b/bin/ryu-manager
@@ -49,11 +49,18 @@ def main():
_args = FLAGS(sys.argv)
log.init_log()
- nw = network.Network()
- dpset_ = dpset.DPSet()
+ # to make non-converted apps work. Once all of them converted,
+ # this will be removed.
+ kwargs = {
+ 'network': network.Network(),
+ 'dpset': dpset.DPSet(),
+ }
app_mgr = AppManager()
- app_mgr.load_apps(FLAGS.app_lists, network=nw, dpset=dpset_)
+ app_mgr.load_apps(FLAGS.app_lists)
+ contexts = app_mgr.create_contexts()
+ contexts.update(kwargs)
+ app_mgr.instantiate_apps(**contexts)
services = []
@@ -67,6 +74,8 @@ def main():
services.append(thr)
gevent.joinall(services)
+ app_mgr.close()
+
if __name__ == "__main__":
main()
diff --git a/ryu/base/app_manager.py b/ryu/base/app_manager.py
index 4aae2903..19e93160 100644
--- a/ryu/base/app_manager.py
+++ b/ryu/base/app_manager.py
@@ -23,24 +23,93 @@ from ryu.controller.handler import register_instance
LOG = logging.getLogger('ryu.base.app_manager')
+class RyuAppContext(object):
+ """
+ Base class for Ryu application context
+ """
+ def __init__(self):
+ super(RyuAppContext, self).__init__()
+
+ def close(self):
+ """
+ teardown method
+ The method name, close, is chosen for python context manager
+ """
+ pass
+
+
+class RyuApp(object):
+ """
+ Base class for Ryu network application
+ """
+ _CONTEXTS = {}
+
+ @classmethod
+ def context_iteritems(cls):
+ """
+ Return iterator over the (key, contxt class) of application context
+ """
+ return cls._CONTEXTS.iteritems()
+
+ def __init__(self, *_args, **_kwargs):
+ super(RyuApp, self).__init__()
+
+ def close(self):
+ """
+ teardown method.
+ The method name, close, is chosen for python context manager
+ """
+ pass
+
+
class AppManager(object):
def __init__(self):
+ self.applications_cls = {}
self.applications = {}
+ self.contexts_cls = {}
+ self.contexts = {}
+
+ def load_apps(self, app_lists):
+ for app_cls_name in itertools.chain.from_iterable([app_list.split(',')
+ for app_list
+ in app_lists]):
+ LOG.info('loading app %s', app_cls_name)
+
+ # for now, only single instance of a given module
+ # Do we need to support multiple instances?
+ # Yes, maybe for slicing.
+ assert app_cls_name not in self.applications_cls
+
+ cls = utils.import_object(app_cls_name)
+ self.applications_cls[app_cls_name] = cls
+
+ for key, context_cls in cls.context_iteritems():
+ cls = self.contexts_cls.setdefault(key, context_cls)
+ assert cls == context_cls
- def load(self, app_mod_name, *args, **kwargs):
- # for now, only single instance of a given module
- # Do we need to support multiple instances?
- # Yes, maybe for slicing.
- assert app_mod_name not in self.applications
+ def create_contexts(self):
+ for key, cls in self.contexts_cls.items():
+ self.contexts[key] = cls()
+ return self.contexts
- cls = utils.import_object(app_mod_name)
- app = cls(*args, **kwargs)
- register_instance(app)
+ def instantiate_apps(self, *args, **kwargs):
+ for app_name, cls in self.applications_cls.items():
+ # for now, only single instance of a given module
+ # Do we need to support multiple instances?
+ # Yes, maybe for slicing.
+ LOG.info('instantiating app %s', app_name)
+ assert app_name not in self.applications
+ app = cls(*args, **kwargs)
+ register_instance(app)
+ self.applications[app_name] = app
- self.applications[app_mod_name] = app
+ def close(self):
+ def close_all(close_dict):
+ for app in close_dict:
+ close_method = getattr(app, 'close', None)
+ if callable(close_method):
+ close_method()
+ close_dict.clear()
- def load_apps(self, app_lists, *args, **kwargs):
- for app in itertools.chain.from_iterable([app_list.split(',')
- for app_list in app_lists]):
- self.load(app, *args, **kwargs)
- LOG.info('loading app %s', app)
+ close_all(self.applications)
+ close_all(self.contexts)