From 4bf7780ccbbd6fc63fd48d21eea24a094522b388 Mon Sep 17 00:00:00 2001
From: Satoshi Kobayashi <satoshi-k@stratosphere.co.jp>
Date: Thu, 23 Jan 2014 15:33:42 +0900
Subject: [PATCH v3] fix bidirectional event confusion

a request includes a reply

Signed-off-by: Satoshi Kobayashi <satoshi-k@stratosphere.co.jp>
---
Changes v1 -> v2:
  - stop using uuid
  - refactoring
Changes v2 -> v3:
  - EventRequestBase includes EventReplyBase
  - remove RyuApp#send_reply()
  - update doc
 doc/source/ryu_app_api.rst           |    5 +++--
 ryu/base/app_manager.py              |   12 +++++-------
 ryu/controller/event.py              |    1 +
 ryu/services/protocols/vrrp/event.py |    2 +-
 4 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/doc/source/ryu_app_api.rst b/doc/source/ryu_app_api.rst
index 06a97df..5c0b536 100644
--- a/doc/source/ryu_app_api.rst
+++ b/doc/source/ryu_app_api.rst
@@ -180,11 +180,12 @@ and block until receiving a reply.
 Returns the received reply.
 The argument should be an instance of EventRequestBase.
 
-send_reply(self, rep)
+reply_to_request(self, req, rep)
 `````````````````````
 
 Send a reply for a synchronous request sent by send_request.
-The argument should be an instance of EventReplyBase.
+The first argument should be an instance of EventRequestBase.
+The second argument should be an instance of EventReplyBase.
 
 send_event(self, name, ev)
 ``````````````````````````
diff --git a/ryu/base/app_manager.py b/ryu/base/app_manager.py
index ebf2196..a4f4e3c 100644
--- a/ryu/base/app_manager.py
+++ b/ryu/base/app_manager.py
@@ -67,7 +67,6 @@ class RyuApp(object):
         self.observers = {}     # ev_cls -> observer-name -> states:set
         self.threads = []
         self.events = hub.Queue(128)
-        self.replies = hub.Queue()
         self.logger = logging.getLogger(self.name)
 
         # prevent accidental creation of instances of this class outside RyuApp
@@ -121,16 +120,13 @@ class RyuApp(object):
 
         return observers
 
-    def send_reply(self, rep):
-        assert isinstance(rep, EventReplyBase)
-        SERVICE_BRICKS[rep.dst].replies.put(rep)
-
     def send_request(self, req):
         assert isinstance(req, EventRequestBase)
         req.sync = True
+        req.reply_q = hub.Queue()
         self.send_event(req.dst, req)
         # going to sleep for the reply
-        return self.replies.get()
+        return req.reply_q.get()
 
     def _event_loop(self):
         while self.is_active or not self.events.empty():
@@ -160,9 +156,11 @@ class RyuApp(object):
             self.send_event(observer, ev, state)
 
     def reply_to_request(self, req, rep):
+        assert isinstance(req, EventRequestBase)
+        assert isinstance(rep, EventReplyBase)
         rep.dst = req.src
         if req.sync:
-            self.send_reply(rep)
+            req.reply_q.put(rep)
         else:
             self.send_event(rep.dst, rep)
 
diff --git a/ryu/controller/event.py b/ryu/controller/event.py
index 8191710..a90bf66 100644
--- a/ryu/controller/event.py
+++ b/ryu/controller/event.py
@@ -26,6 +26,7 @@ class EventRequestBase(EventBase):
         self.dst = None  # app.name of provide the event.
         self.src = None
         self.sync = False
+        self.reply_q = None
 
 
 class EventReplyBase(EventBase):
diff --git a/ryu/services/protocols/vrrp/event.py b/ryu/services/protocols/vrrp/event.py
index 686f9ce..b1872c6 100644
--- a/ryu/services/protocols/vrrp/event.py
+++ b/ryu/services/protocols/vrrp/event.py
@@ -174,7 +174,7 @@ class EventVRRPConfigRequest(event.EventRequestBase):
 
 class EventVRRPConfigReply(event.EventReplyBase):
     def __init__(self, instance_name, interface, config):
-        # dst = None. dst is filled by app_base.RyuApp.send_reply()
+        # dst = None. dst is filled by app_base.RyuApp#reply_to_request()
         super(EventVRRPConfigReply, self).__init__(None)
         self.instance_name = instance_name  # None means failure
         self.interface = interface
-- 
1.7.1

