Thank you Murphy. I noticed that you also added this info in the POX wiki yesterday. That should be really helpful. Much appreciated.
On Nov 11, 2013, at 9:26 PM, Murphy McCauley <[email protected]> wrote: > On Nov 11, 2013, at 4:31 AM, Giannis Sapountzis <[email protected]> wrote: > >> Hello everyone. >> >> I'm looking for some explanation on event handling in POX. > > There's quite a bit of explanation on this subject in the POX manual and in > the reference (docstrings). > >> Lets say that i have 2 components registered in core with names Component_1 >> and Component_2. Component_1 raises some event called Event_1. > > Just a sidenote: components and events in POX are both classes, and POX's > naming convention uses TitleCase for these -- with no underscores. Names with > underscores like yours should work fine with the more explicit functions > (e.g., addListener), but you may find that some of the convenience features > of POX expect POX style naming (e.g., listen_to_dependencies). > >> I want to handle some events in Component_2 both from core.openflow and from >> core.Component_1. >> >> How should i name the handler methods in Component_2 and how should i >> register the listeners? Is the following example correct? > > As described in the manual, you can name them whatever you want if you set up > the bindings yourself using addListener() or addListenerByName(). If you > want to use addListeners(), you have to name them _handle_<EventName> or > _handle_<Prefix>_<EventName>, where EventName is the name of the event type > and Prefix is the prefix as specified in the call to addListeners. > > If you want to use core.listen_to_dependencies, you have to name them > _handle_<ObjectOnCore>_<EventName> by default, where ObjectOnCore is the name > of the object (which is registered on core) which is sourcing the events you > want. (More on this below.) > >> In Component_2: >> >> __init__(self): >> core.Component_1.addListeners(self) >> core.openflow.addListeners(self) >> >> def _handle_openflow_ConnectionUp(self): >> …. >> >> def _handle_Component_1_Event_1(self): >> …. > > Since you're using addListeners here with no prefix, it'd just be > _handle_ConnectionUp. You could use the prefix argument of addListeners() to > make it _handle_WhateverYouLike_ConnectionUp. If you're going to be handling > events from multiple sources, this isn't a bad idea (to make sure that two > sources don't try to fire the same handler). listen_to_dependencies() just > automatically makes the prefix the name of the component on core. > >> Secondly, i only want a component to start handling events afar having >> received a notification from another component. Can i add the listeners only >> after i have "caught" an event? Something like the following: >> >> __init__(self): >> core.Component_1.addListeners(self) >> >> def _handle_Component_1_Event_1(self): >> core.openflow.addListeners(self) > > Indeed, you can do this (though the above example has prefix/name issues). > >> Third, can someone explain to me what the core.listen_to_dependencies does? > > Here's the docstring. You can get it yourself by reading the code, starting > POX with the Python shell (py component) and doing > "help(core.listen_to_dependencies)", or by building the pydoc or Sphinx > documentation (neither of which are as accessible/used as they should be, but > see POX's custom pydoc in the tools directory for the former and the pox-doc > repo for the latter). > > listen_to_dependencies(self, sink, components=None, attrs=True, > short_attrs=False, listen_args={}) method of pox.core.POXCore instance > Look through *sink* for handlers named like _handle_component_event. > Use that to build a list of components, and append any components > explicitly specified by *components*. > > listen_args is a dict of "component_name"={"arg_name":"arg_value",...}, > allowing you to specify additional arguments to addListeners(). > > When all the referenced components are registered, do the following: > 1) Set up all the event listeners > 2) Call "_all_dependencies_met" on *sink* if it exists > 3) If attrs=True, set attributes on *sink* for each component > (e.g, sink._openflow_ would be set to core.openflow) > > For example, if topology is a dependency, a handler for topology's > SwitchJoin event must be defined as so: > def _handle_topology_SwitchJoin (self, ...): > > > -- Murphy
