Hi,

(2013/02/20 11:37), Isaku Yamahata wrote:
> General comment. Some of logic could be generic, not specific to
> datapath tracking.
>
Thanks for your comment.

>> +class DatapathDiscovery(app_manager.RyuApp):
>> +    _EVENTS = [EventDPEnter, EventDPLeave,
>> +               EventDPPortAdd, EventDPPortDelete, EventDPPortModify]
>> +
>> +    def __init__(self):
>> +        super(DatapathDiscovery, self).__init__()
>> +
>> +        self.dpids = []   # datapath_id
>> +        self.ports = {}  # datapath_id => ports
>> +        # OFPP_MAX might be different when using multiple version of 
>> OpenFlow?
>> +        self._OFPP_MAX = {}  # datapath_id => OFPP_MAX
>
> Why not whole ofproto? How about
> self.dpids = dict: dpid -> the pair (ofproto, ports)?
> Thus the logic of _unregister() will be simplified.
> Possibly we'd like to introduce another class to describe the pair.
>
sounds better.
I'll fix and post it.

>> +    def _add_port(self, dpid, port_no):
>> +        if port_no > self._OFPP_MAX[dpid]:
>> +            # LOG.debug('port %s is reserved', port_no)
>> +            return
>> +
>> +        self.ports.setdefault(dpid, [])
>> +        self.ports[dpid].append(port_no)
>
>             self.ports.setdefault(dpid, []).append(port_no)
> dict.setdefault() returns value.
>
I see.

>> +    @handler.set_ev_cls(ofp_event.EventOFPPortStatus, 
>> handler.MAIN_DISPATCHER)
>> +    def port_status_handler(self, ev):
>> +        msg = ev.msg
>> +        reason = msg.reason
>> +        dpid = msg.datapath.id
>> +        port_no = msg.desc.port_no
>> +        ofproto = msg.datapath.ofproto
>> +
>> +        if reason == ofproto.OFPPR_ADD:
>> +            LOG.debug('port was added.' +
>> +                      '(datapath id = %s, port number = %s)',
>> +                      dpid, port_no)
>> +            self._add_port(dpid, port_no)
>> +            self.send_event_to_observers(EventDPPortAdd(dpid, port_no))
>> +
>> +        elif reason == ofproto.OFPPR_DELETE:
>> +            LOG.debug('port was deleted.' +
>> +                      '(datapath id = %s, port number = %s)',
>> +                      dpid, port_no)
>> +            self._del_port(dpid, port_no)
>> +            self.send_event_to_observers(EventDPPortDelete(dpid, port_no))
>> +
>> +        else:
>> +            assert reason == ofproto.OFPPR_MODIFY
>> +            LOG.debug('port was modified.' +
>> +                      '(datapath id = %s, port number = %s)',
>> +                      dpid, port_no)
>> +            self.send_event_to_observers(EventDPPortModify(dpid, port_no))
>
> Doesn't this track port state like link up/down.
>
OK, I'll try to track modify state.
Has OFPPR_MODIFY some parameters?
In dpset.py, PortState.add and PortState.modify are same code.

>> +    @handler.set_ev_cls(EventDPListRequest)
>> +    def request_handler(self, ev):
>> +        dpid = ev.dpid
>> +        # LOG.debug(ev)
>> +        if dpid is None:
>> +            dpids = self.dpids
>> +            ports = self.ports
>> +        elif dpid in self.dpids:
>> +            dpids = [dpid]
>> +            ports = [self.ports[dpid]]
>> +        else:
>> +            dpids = []
>> +            ports = {}
>> +
>> +        reply = EventDPListReply(self.name, ev, dpids, ports)
>> +        self.send_event(ev.src, reply)
>
> This logic can be generalized and can be a method in AppManager or RyuApp.
OK, I'll try to generalize it.

> This needs to be blocked and wait request.
> gevent.event (or equivalent primitive) can be used to blocking.
>
Could you explain it in more detail?
What number of line should be blocked?

>> +    def _get_dp_list(self, dpid=None):
>> +        request = EventDPListRequest(self.name, dpid)
>> +        self.send_event(datapath.DatapathDiscovery.__name__, request)
>> +        # assume that replys are in right order
>> +        reply = self.replys.get(timeout=self._REQUEST_TIMEOUT)
>> +        assert reply.request == request
>> +        return reply
>> +
>> +    def _request_loop(self):
>> +        while self.is_active:
>> +            dp_list_all = self._get_dp_list()
>> +            LOG.debug('ALL DPList: %s', dp_list_all)
>> +            dp1 = self._get_dp_list(1)
>> +            LOG.debug('DP1: %s', dp1)
>> +            gevent.sleep(10)
>
> I thinks this is just for debug/showing how to use, so it's just ok for now.
> But we need more generic way to snoop event queuing.
> Probably registering observer with the list of (brick name, event class).
>
That's right.

>> +class EventRequestBase(event.EventBase):
>> +    def __init__(self, src):
>> +        self.src = src  # brick name of event source
>
> EventRequestBase and EventReplyBase is generic enough to be in event.py
>
I see.

>> +class EventReplyBase(event.EventBase):
>> +    def __init__(self, src, request):
>> +        self.src = src  # brick name of event source
>> +        assert issubclass(request.__class__, EventRequestBase)
>                    isinstance(request, EventRequestBase)
>
Oh, thanks.

>> +        self.request = request
>
> request is an object which is not suitable to be encoded in event.
> How about Event{Request, Reply}Base.xid and use id(request)?
 > And more we'd like to a framework to snoop into request/reply.
 >
That sounds better.
I'd like to just identify the corresponding request.


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