On Tue, 26 Feb 2013 18:23:12 +0900
Isaku Yamahata <[email protected]> wrote:

> On Sun, Feb 24, 2013 at 12:39:29PM +0900, FUJITA Tomonori wrote:
>> Why a source needs to send an event in the first place?
> 
> Basically looks good. Some minor nits inlined

Thanks, I've applied the following.

=
>From 6690d519dc0230ed21540f35b762197eeeb8745e Mon Sep 17 00:00:00 2001
From: FUJITA Tomonori <[email protected]>
Date: Wed, 27 Feb 2013 21:24:03 +0900
Subject: [PATCH] RyuApp: allows observers to specify state

This fixes the following exception:

>   $ ryu-manager ryu_app(OF1.2 app)
>   $ sudo mn --controller remote 127.0.0.1
>   $ sudo ovs-vsctl set bridge s1 protocols='[OpenFlow10,OpenFlow12]'
> connected socket:<socket fileno=4 sock=127.0.0.1:6633 peer=127.0.0.1:60456> 
> address:('127.0.0.1', 60456)
> EVENT ofp_event->dpset EventOFPStateChange
> connected socket:<socket fileno=10 sock=127.0.0.1:6633 peer=127.0.0.1:60457> 
> address:('127.0.0.1', 60457)
> EVENT ofp_event->dpset EventOFPStateChange
> hello ev <ryu.controller.ofp_event.EventOFPHello object at 0x11bf550>
> unsupported version 0x1. If possible, set the switch to use one of the 
> versions [3]
> error msg ev version: 0x3 msg_type 0x1 xid 0xc84d9220 type 0x1 code 0x1 0x3 
> 0x1 0x0 0x5f 0xc8 0x4d 0x92 0x20 0x0 0x0 0x0 0x0 0x75 0x6e 0x73 0x75 0x70 
> 0x70 0x6f
> +0x72 0x74 0x65 0x64 0x20 0x76 0x65 0x72 0x73 0x69 0x6f 0x6e 0x20 0x30 0x78 
> 0x31 0x2e 0x20 0x49 0x66 0x20 0x70 0x6f 0x73 0x73 0x69 0x62 0x6c 0x65 0x2c 
> 0x20 0x73
> +0x65 0x74 0x20 0x74 0x68 0x65 0x20 0x73 0x77 0x69 0x74 0x63 0x68
> EVENT ofp_event->dpset EventOFPPortStatus
> DPSET: A port was modified.(datapath id = None, port number = 1)
> Traceback (most recent call last):
>   File "/usr/lib/python2.7/dist-packages/gevent/greenlet.py", line 390, in run
>     result = self._run(*self.args, **self.kwargs)
>   File 
> "/usr/local/lib/python2.7/dist-packages/ryu-1.6-py2.7.egg/ryu/base/app_manager.py",
>  line 86, in _event_loop
>     handler(ev)
>   File 
> "/usr/local/lib/python2.7/dist-packages/ryu-1.6-py2.7.egg/ryu/controller/dpset.py",
>  line 192, in port_status_handler
>     self.port_state[datapath.id].modify(port.port_no, port)
> KeyError: None
> <Greenlet at 0x11bc518: <bound method DPSet._event_loop of 
> <ryu.controller.dpset.DPSet object at 0xd0df10>>> failed with KeyError

Reported-by: HIYAMA Manabu <[email protected]>
Signed-off-by: FUJITA Tomonori <[email protected]>
---
 ryu/base/app_manager.py      |   22 ++++++++++++++--------
 ryu/controller/controller.py |    4 ++--
 2 files changed, 16 insertions(+), 10 deletions(-)

diff --git a/ryu/base/app_manager.py b/ryu/base/app_manager.py
index 1a2567e..d977b40 100644
--- a/ryu/base/app_manager.py
+++ b/ryu/base/app_manager.py
@@ -69,15 +69,20 @@ class RyuApp(object):
         self.event_handlers.setdefault(ev_cls, [])
         self.event_handlers[ev_cls].append(handler)
 
-    def register_observer(self, ev_cls, name):
-        self.observers.setdefault(ev_cls, [])
-        self.observers[ev_cls].append(name)
+    def register_observer(self, ev_cls, name, states=None):
+        states = states or []
+        self.observers.setdefault(ev_cls, {})[name] = states
 
     def get_handlers(self, ev):
         return self.event_handlers.get(ev.__class__, [])
 
-    def get_observers(self, ev):
-        return self.observers.get(ev.__class__, [])
+    def get_observers(self, ev, state):
+        observers = []
+        for k, v in self.observers.get(ev.__class__, {}).iteritems():
+            if not state or not v or state in v:
+                observers.append(k)
+
+        return observers
 
     def _event_loop(self):
         while True:
@@ -98,8 +103,8 @@ class RyuApp(object):
             LOG.debug("EVENT LOST %s->%s %s" %
                       (self.name, name, ev.__class__.__name__))
 
-    def send_event_to_observers(self, ev):
-        for observer in self.get_observers(ev):
+    def send_event_to_observers(self, ev, state=None):
+        for observer in self.get_observers(ev, state):
             self.send_event(observer, ev)
 
     def close(self):
@@ -184,7 +189,8 @@ class AppManager(object):
                     name = m.observer.split('.')[-1]
                     if name in SERVICE_BRICKS:
                         brick = SERVICE_BRICKS[name]
-                        brick.register_observer(m.ev_cls, i.name)
+                        brick.register_observer(m.ev_cls, i.name,
+                                                m.dispatchers)
 
                 # allow RyuApp and Event class are in different module
                 if hasattr(m, 'ev_cls'):
diff --git a/ryu/controller/controller.py b/ryu/controller/controller.py
index da59ab9..bf53f7e 100644
--- a/ryu/controller/controller.py
+++ b/ryu/controller/controller.py
@@ -141,7 +141,7 @@ class Datapath(object):
         self.state = state
         ev = ofp_event.EventOFPStateChange(self)
         ev.state = state
-        self.ofp_brick.send_event_to_observers(ev)
+        self.ofp_brick.send_event_to_observers(ev, state)
 
     def set_version(self, version):
         assert version in self.supported_ofp_version
@@ -175,7 +175,7 @@ class Datapath(object):
                     if self.state in handler.dispatchers:
                         handler(ev)
 
-                self.ofp_brick.send_event_to_observers(ev)
+                self.ofp_brick.send_event_to_observers(ev, self.state)
 
                 buf = buf[required_len:]
                 required_len = ofproto_common.OFP_HEADER_SIZE
-- 
1.7.4.4


------------------------------------------------------------------------------
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