On Wed, 20 Feb 2013 14:21:27 +0900
Isaku Yamahata <[email protected]> wrote:
> This fixes the following exception.
> This is because observer handler is called independent on event source state.
> So teach event dispatcher event source state.
>
>> $ 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: Isaku Yamahata <[email protected]>
> ---
> ryu/base/app_manager.py | 26 ++++++++++++++------------
> ryu/controller/controller.py | 4 ++--
> 2 files changed, 16 insertions(+), 14 deletions(-)
>
> diff --git a/ryu/base/app_manager.py b/ryu/base/app_manager.py
> index a9895a2..d2dae91 100644
> --- a/ryu/base/app_manager.py
> +++ b/ryu/base/app_manager.py
> @@ -80,26 +80,28 @@ class RyuApp(object):
>
> def _event_loop(self):
> while True:
> - ev = self.events.get()
> + ev, state = self.events.get()
> handlers = self.get_handlers(ev)
> for handler in handlers:
> - handler(ev)
> + if (state is None or handler.dispatchers is None or
> + state in handler.dispatchers):
> + handler(ev)
>
> - def _send_event(self, ev):
> - self.events.put(ev)
> + def _send_event(self, ev, state):
> + self.events.put((ev, state))
>
> - def send_event(self, name, ev):
> + def send_event(self, name, ev, state=None):
> if name in SERVICE_BRICKS:
> - LOG.debug("EVENT %s->%s %s" %
> - (self.name, name, ev.__class__.__name__))
> - SERVICE_BRICKS[name]._send_event(ev)
> + LOG.debug("EVENT %s->%s %s %s",
> + self.name, name, ev.__class__.__name__, state)
> + SERVICE_BRICKS[name]._send_event(ev, state)
> else:
> - LOG.debug("EVENT LOST %s->%s %s" %
> - (self.name, name, ev.__class__.__name__))
> + LOG.debug("EVENT LOST %s->%s %s %s",
> + self.name, name, ev.__class__.__name__, state)
Why a source needs to send an event in the first place?
diff --git a/ryu/base/app_manager.py b/ryu/base/app_manager.py
index a9895a2..5934126 100644
--- a/ryu/base/app_manager.py
+++ b/ryu/base/app_manager.py
@@ -68,15 +68,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=[]):
+ self.observers.setdefault(ev_cls, {})
+ self.observers[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:
@@ -97,8 +102,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):
@@ -182,7 +187,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)
for brick, i in SERVICE_BRICKS.items():
LOG.debug("BRICK %s" % brick)
diff --git a/ryu/controller/controller.py b/ryu/controller/controller.py
index 9dc745a..38c4fe9 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
------------------------------------------------------------------------------
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