Thanks, I can confirm that with the patch my example works as I originally
anticipated - the handler for Echo Request for the main dispatcher is the
only method called when an Echo Request is received.

Regards,
Alan Barr
On 4 Jul 2013 05:39, "Isaku Yamahata" <[email protected]> wrote:

Looks like a bug.
Can you please test this patch?

>From 34a3c034c3d67b73c0a806195e9984f95a381bf3 Mon Sep 17 00:00:00 2001
Message-Id: <
34a3c034c3d67b73c0a806195e9984f95a381bf3.1372911748.git.yamah...@valinux.co.jp
>
In-Reply-To: <[email protected]>
References: <[email protected]>
From: Isaku Yamahata <[email protected]>
Date: Thu, 4 Jul 2013 13:07:15 +0900
Subject: [PATCH] ryu/base/app_manager.py: teach state

Signed-off-by: Isaku Yamahata <[email protected]>
---
 ryu/base/app_manager.py |   32 +++++++++++++++++++-------------
 1 file changed, 19 insertions(+), 13 deletions(-)

diff --git a/ryu/base/app_manager.py b/ryu/base/app_manager.py
index 173e35c..c666f2c 100644
--- a/ryu/base/app_manager.py
+++ b/ryu/base/app_manager.py
@@ -57,8 +57,8 @@ class RyuApp(object):
     def __init__(self, *_args, **_kwargs):
         super(RyuApp, self).__init__()
         self.name = self.__class__.__name__
-        self.event_handlers = {}
-        self.observers = {}
+        self.event_handlers = {}        # ev_cls -> handlers:list
+        self.observers = {}     # ev_cls -> observer-name -> states:set
         self.threads = []
         self.events = hub.Queue(128)
         self.replies = hub.Queue()
@@ -71,11 +71,17 @@ class RyuApp(object):
         self.event_handlers[ev_cls].append(handler)

     def register_observer(self, ev_cls, name, states=None):
-        states = states or []
-        self.observers.setdefault(ev_cls, {})[name] = states
+        states = states or set()
+        ev_cls_observers = self.observers.setdefault(ev_cls, {})
+        ev_cls_observers.setdefault(name, set()).update(states)

-    def get_handlers(self, ev):
-        return self.event_handlers.get(ev.__class__, [])
+    def get_handlers(self, ev, state=None):
+        handlers = self.event_handlers.get(ev.__class__, [])
+        if state is None:
+            return handlers
+
+        return [handler for handler in handlers
+                if not handler.dispatchers or state in handler.dispatchers]

     def get_observers(self, ev, state):
         observers = []
@@ -98,28 +104,28 @@ class RyuApp(object):

     def _event_loop(self):
         while True:
-            ev = self.events.get()
-            handlers = self.get_handlers(ev)
+            ev, state = self.events.get()
+            handlers = self.get_handlers(ev, state)
             for handler in handlers:
                 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:
             if isinstance(ev, EventRequestBase):
                 ev.src = self.name
             LOG.debug("EVENT %s->%s %s" %
                       (self.name, name, ev.__class__.__name__))
-            SERVICE_BRICKS[name]._send_event(ev)
+            SERVICE_BRICKS[name]._send_event(ev, state)
         else:
             LOG.debug("EVENT LOST %s->%s %s" %
                       (self.name, name, ev.__class__.__name__))

     def send_event_to_observers(self, ev, state=None):
         for observer in self.get_observers(ev, state):
-            self.send_event(observer, ev)
+            self.send_event(observer, ev, state)

     def reply_to_request(self, req, rep):
         rep.dst = req.src
--
1.7.10.4



On Wed, Jul 03, 2013 at 09:50:50AM +0100, Alan Barr wrote:
> Thanks for your reply, please find code and output below.
>
>
>
> I have done some minimal debugging, and know that register_observer is
over
> writing the states for the app class each time it is called. It expects
one
> method with multiple states instead of multiple methods each registered
for one
> state.
>
> Granted, I don?t fully understand this process yet as I?m not sure why the
> method along with the class is not being stored - though I feel this may
be
> part of the problem. I haven?t looked at where the events are being
picked up
> by the observers yet ? which must be responsible for calling all of the
> registered methods for this event, regardless of their registered
dispatcher.
>
>
>
>
>
> ##### CODE #####
>
> import logging
>
> import struct
>
>
>
> from ryu.base import app_manager
>
> from ryu.controller import mac_to_port
>
> from ryu.controller import ofp_event
>
> from ryu.controller.handler import set_ev_cls
>
> from ryu.ofproto import ofproto_v1_3
>
> from ryu.ofproto import ofproto_v1_3_parser
>
> from ryu.lib.mac import haddr_to_str
>
>
>
> from ryu.controller.controller import Datapath
>
> from ryu.controller.handler import HANDSHAKE_DISPATCHER
>
> from ryu.controller.handler import CONFIG_DISPATCHER
>
> from ryu.controller.handler import DEAD_DISPATCHER
>
> from ryu.controller.handler import MAIN_DISPATCHER
>
>
>
> class PacketTesting(app_manager.RyuApp):
>
>     OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION]
>
>
>
>     def __init__(self, *args, **kwargs):
>
>         super(PacketTesting, self).__init__(*args, **kwargs)
>
>
>
>     @set_ev_cls(ofp_event.EventOFPEchoRequest, MAIN_DISPATCHER)
>
>     def _echo_rep_main(self, ev):
>
>         print "DEBUG: In Handler for Echo Request (Main)"
>
>
>
>     @set_ev_cls(ofp_event.EventOFPEchoRequest, CONFIG_DISPATCHER)
>
>     def _echo_rep_conf(self, ev):
>
>         print "DEBUG: In Handler for Echo Request (Config)"
>
>
>
>     @set_ev_cls(ofp_event.EventOFPEchoRequest, HANDSHAKE_DISPATCHER)
>
>     def _echo_rep_hand(self, ev):
>
>         print "DEBUG: In Handler for Echo Request (Handshake)"
>
>
>
>     @set_ev_cls(ofp_event.EventOFPEchoRequest, DEAD_DISPATCHER)
>
>     def _echo_rep_dead(self, ev):
>
>         print "DEBUG: In Handler for Echo Request (Dead)"
>
>
>
>
>
> ##### OUTPUT #####
>
>
>
> loading app ../ryu_echo_req_ex.py
>
> loading app ryu.controller.ofp_handler
>
> instantiating app ../ryu_echo_req_ex.py
>
> instantiating app ryu.controller.ofp_handler
>
> BRICK PacketTesting
>
>   CONSUMES EventOFPEchoRequest
>
> BRICK ofp_event
>
>   PROVIDES EventOFPEchoRequest TO {'PacketTesting': ['main']}
>
>   CONSUMES EventOFPErrorMsg
>
>   CONSUMES EventOFPEchoRequest
>
>   CONSUMES EventOFPSwitchFeatures
>
>   CONSUMES EventOFPHello
>
> connected socket:<eventlet.greenio.GreenSocket object at 0xa0fb84c>
address:
> ('127.0.0.1', 60098)
>
> hello ev <ryu.controller.ofp_event.EventOFPHello object at 0xa0fbb6c>
>
> move onto config mode
>
> switch features ev version: 0x4 msg_type 0x6 xid 0xf8480126
OFPSwitchFeatures
> (auxiliary_id=0,capabilities=71,datapath_id=153,n_buffers=256,n_tables=
> 254,reserved=0)
>
> move onto main mode
>
> EVENT ofp_event->PacketTesting EventOFPEchoRequest
>
> DEBUG: In Handler for Echo Request (Config)
>
> DEBUG: In Handler for Echo Request (Dead)
>
> DEBUG: In Handler for Echo Request (Handshake)
>
> DEBUG: In Handler for Echo Request (Main)
>
> EVENT ofp_event->PacketTesting EventOFPEchoRequest
>
> DEBUG: In Handler for Echo Request (Config)
>
> DEBUG: In Handler for Echo Request (Dead)
>
> DEBUG: In Handler for Echo Request (Handshake)
>
> DEBUG: In Handler for Echo Request (Main)
>
> On 3 Jul 2013 07:41, "Isaku Yamahata" <[email protected]> wrote:
>
>     Your expectation sounds correct. Posting your code would help.
>
>     thanks,
>
>     On Tue, Jul 02, 2013 at 01:54:20PM +0100, Alan Barr wrote:
>     > Hello all,
>     >
>     >
>     >
>     > I was wondering if someone could clarify if what I am seeing is
expected
>     > behaviour.
>     >
>     > I am new to Ryu and currently trying to familiarise myself with it.
>     >
>     > In one of my test applications I have registered four different
methods
>     for
>     > EventOFPEchoRequest, one method for each of HANDSHAKE, CONFIG, MAIN
and
>     DEAD
>     > dispatchers.
>     >
>     > When this event is triggered, all of these methods are called, not
just
>     the one
>     > registered for the appropriate state.
>     >
>     >
>     >
>     > Is this the correct behaviour? I don't have a valid use case of
this, I'm
>     just
>     > trying to better understand Ryu and this was my first test setup. I
wasn?
>     t
>     > expecting this behaviour.
>     >
>     >
>     >
>     > I was basing this off:
>     >
>     >
>     >
>     > ?A decorator for Ryu application to declare an event handler.
Decorated
>     method
>     > will become an event handler. ev_cls is an event class whose
instances
>     this
>     > RyuApp wants to receive. dispatchers argument specifies one of the
>     following
>     > negotiation phases (or a list of them) for which events should be
>     generated for
>     > this handler. Note that, in case an event changes the phase, the
phase
>     before
>     > the change is used to check the interest.?
https://github.com/osrg/ryu/
>     wiki/API
>     >
>     >
>     >
>     > I'm on commit a66bcf031d782c25b987431feb76251970158573.
>     >
>     >
>     >
>     > Kind Regards,
>     >
>     > Alan Barr
>     >
>     >
>     >
>
>     >
>
------------------------------------------------------------------------------
>     > This SF.net email is sponsored by Windows:
>     >
>     > Build for Windows Store.
>     >
>     > http://p.sf.net/sfu/windows-dev2dev
>     > _______________________________________________
>     > Ryu-devel mailing list
>     > [email protected]
>     > https://lists.sourceforge.net/lists/listinfo/ryu-devel
>
>
>     --
>     yamahata
>
>
------------------------------------------------------------------------------
>     This SF.net email is sponsored by Windows:
>
>     Build for Windows Store.
>
>     http://p.sf.net/sfu/windows-dev2dev
>     _______________________________________________
>     Ryu-devel mailing list
>     [email protected]
>     https://lists.sourceforge.net/lists/listinfo/ryu-devel
>

>
------------------------------------------------------------------------------
> This SF.net email is sponsored by Windows:
>
> Build for Windows Store.
>
> http://p.sf.net/sfu/windows-dev2dev
> _______________________________________________
> Ryu-devel mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/ryu-devel


--
yamahata

------------------------------------------------------------------------------
This SF.net email is sponsored by Windows:

Build for Windows Store.

http://p.sf.net/sfu/windows-dev2dev
_______________________________________________
Ryu-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ryu-devel
------------------------------------------------------------------------------
This SF.net email is sponsored by Windows:

Build for Windows Store.

http://p.sf.net/sfu/windows-dev2dev
_______________________________________________
Ryu-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ryu-devel

Reply via email to