So far application context which is shared by applications are created
by ryu-manager. And it passes them to each applications.
However it doesn't scale as many applications come in.
So introduce a layer for each application to specify necessary contexts.

Signed-off-by: Isaku Yamahata <[email protected]>
---
 bin/ryu-manager         |   15 +++++-
 ryu/base/app_manager.py |  117 +++++++++++++++++++++++++++++++++++++++++------
 2 files changed, 115 insertions(+), 17 deletions(-)

diff --git a/bin/ryu-manager b/bin/ryu-manager
index f9bc562..0c17aec 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.create_dpset()
+    # to make non-converted apps work. Once all of them converted,
+    # this will be removed.
+    kwargs = {
+        'network': network.Network(),
+        'dpset': dpset.create_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 4aae290..aa46788 100644
--- a/ryu/base/app_manager.py
+++ b/ryu/base/app_manager.py
@@ -23,24 +23,113 @@ from ryu.controller.handler import register_instance
 LOG = logging.getLogger('ryu.base.app_manager')
 
 
+_NOARG_APP_CONTEXTS = {}
+
+
+def noarg_app_context_factory(cls):
+    """
+    wrapper function to context
+    Ryu application contexts requires cls.__init__(self, *args, **kwargs)
+    This functions wraps the class whose init signature is __init__(self)
+    """
+    if cls in _NOARG_APP_CONTEXTS:
+        return _NOARG_APP_CONTEXTS[cls]
+
+    def _noarg_app_context_factory(*_args, **_kwargs):
+        return cls()
+    _NOARG_APP_CONTEXTS[cls] = _noarg_app_context_factory
+    return _noarg_app_context_factory
+
+
+class RyuAppContext(object):
+    """
+    Base class for Ryu application context
+    """
+    def __init__(self, *_args, **_kwargs):
+        super(RyuAppContext, self).__init__()
+
+    def close(self):
+        pass
+
+
+class RyuApp(object):
+    """
+    Base class for Ryu network application
+    """
+    _CONTEXTS = {}
+
+    @classmethod
+    def context_dict(cls):
+        """
+        Return list of application context
+        """
+        return cls._CONTEXTS
+
+    @classmethod
+    def context_create(cls, name, *args, **kwargs):
+        """
+        Return application context
+        """
+        return cls._CONTEXTS[name](*args, **kwargs)
+
+    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_dict().items():
+                cls = self.contexts_cls.setdefault(key, context_cls)
+                assert cls == context_cls
+
+    def create_contexts(self, *args, **kwargs):
+        for key, cls in self.contexts_cls.items():
+            self.contexts[key] = cls(*args, **kwargs)
+        return self.contexts
 
-    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 instantiate_apps(self, *args, **kwargs):
+        kwargs.update(self.contexts)
 
-        cls = utils.import_object(app_mod_name)
-        app = cls(*args, **kwargs)
-        register_instance(app)
+        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)
-- 
1.7.1.1


------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
Ryu-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ryu-devel

Reply via email to