On Fri, Feb 22, 2013 at 07:14:19PM +0900, YAMADA Hideki wrote:
> Now, direct method calling is used for app-to-app communication,
> via _CONTEXTS parameters.
> This patch is more loose coupling way than direct way.
> 
> Signed-off-by: YAMADA Hideki <[email protected]>
> ---
>  ryu/base/app_manager.py |   29 +++++++++++++++++++++++++++++
>  ryu/controller/event.py |   17 +++++++++++++++++
>  2 files changed, 46 insertions(+), 0 deletions(-)
> 
> diff --git a/ryu/base/app_manager.py b/ryu/base/app_manager.py
> index 1a2567e..922130a 100644
> --- a/ryu/base/app_manager.py
> +++ b/ryu/base/app_manager.py
> @@ -24,6 +24,7 @@ from gevent.queue import Queue
>  from ryu import utils
>  from ryu.controller.handler import register_instance
>  from ryu.controller.controller import Datapath
> +from ryu.controller.event import EventRequestBase, EventReplyBase
>  
>  LOG = logging.getLogger('ryu.base.app_manager')
>  
> @@ -62,6 +63,7 @@ class RyuApp(object):
>          self.observers = {}
>          self.threads = []
>          self.events = Queue()
> +        self.replys = Queue()
>          self.threads.append(gevent.spawn(self._event_loop))
>  
>      def register_handler(self, ev_cls, handler):
> @@ -82,6 +84,10 @@ class RyuApp(object):
>      def _event_loop(self):
>          while True:
>              ev = self.events.get()
> +
> +            if isinstance(ev, EventReplyBase):
> +                self.replys.put(ev)
> +
>              handlers = self.get_handlers(ev)
>              for handler in handlers:
>                  handler(ev)
> @@ -102,6 +108,29 @@ class RyuApp(object):
>          for observer in self.get_observers(ev):
>              self.send_event(observer, ev)
>  
> +    def send_request(self, dst, ev):
> +        assert isinstance(ev, EventRequestBase)
> +        ev.src = self.name
> +        self.send_event(dst, ev)
> +
> +    def send_reply(self, request, ev):
> +        assert isinstance(request, EventRequestBase)
> +        assert isinstance(ev, EventReplyBase)
> +        ev.src = self.name
> +        ev.xid = request.xid
> +        self.send_event(request.src, ev)
> +
> +    def recv_reply(self, xid):
> +        # waiting for reply
> +        while True:
> +            reply = self.replys.get()  # blocking when empty
> +            if reply.xid == xid:
> +                #LOG.debug('receive reply(xid=%s)', reply.xid)
> +                return reply
> +            else:
> +                #LOG.debug('put off reply(xid=%s)', reply.xid)
> +                self.replys.put(reply)
> +
>      def close(self):
>          """
>          teardown method.

requeuing result seems ugly. How about something like this?
(totally untested. Just for showing intention.)

diff --git a/ryu/base/app_manager.py b/ryu/base/app_manager.py
index a9895a2..5c5d240 100644
--- a/ryu/base/app_manager.py
+++ b/ryu/base/app_manager.py
@@ -61,6 +61,7 @@ class RyuApp(object):
         self.observers = {}
         self.threads = []
         self.events = Queue()
+        self.replys = {}
         self.threads.append(gevent.spawn(self._event_loop))
 
     def register_handler(self, ev_cls, handler):
@@ -101,6 +102,47 @@ class RyuApp(object):
         for observer in self.get_observers(ev):
             self.send_event(observer, ev)
 
+    def send_request(self, dst, ev):
+        assert isinstance(ev, EventRequestBase)
+        ev.src = self.name
+        self.send_event(dst, ev)
+
+    def send_reply(self, request, ev):
+        assert isinstance(request, EventRequestBase)
+        assert isinstance(ev, EventReplyBase)
+        ev.src = self.name
+        ev.xid = request.xid
+        # self.send_event_to_observers(ev)
+        self.send_event(request.src, ev)
+
+    def send_requst_block(self, dst, ev):
+        assert ev.xid not in self.replys
+        async_result = gevent.event.AsyncResult()
+        self.replys[ev.xid] = async_result
+        self.send_request(dst, ev)
+        return async_result.get()
+
+    def reply_handler(self, ev):
+        """ This handler is called by handler.
+        e.g.
+        class MyRequestEvent(EventRequetBase):
+            ...
+
+        class MyReplyEvent(EventReplayBase):
+            ...
+
+        class MyRequester(RyuApp):
+            def request(self):
+                ...
+                reply = self.send_request_block(dst, ev)
+
+            @handler.set_ev_cls(MyReplyEvent)
+            def my_reply_handler(self, ev):
+                self.reply_handler(ev)
+        """
+        async_result = self.replys.pop(ev.xid)
+        async_result.set(ev)
+
     def close(self):
         """
         teardown method.

-- 
yamahata

------------------------------------------------------------------------------
Everyone hates slow websites. So do we.
Make your web apps faster with AppDynamics
Download AppDynamics Lite for free today:
http://p.sf.net/sfu/appdyn_d2d_feb
_______________________________________________
Ryu-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ryu-devel

Reply via email to