func (c *Collector) Rcv(m beehive.Msg, ctx beehive.RcvContext) error { res := m.Data().(StatResult) glog.V(2).Infof("Stat results: %+v", res) matrix := ctx.Dict(matrixDict) key := res.Switch.Key() v, err := matrix.Get(key) if err != nil { return fmt.Errorf("No such switch in matrix: %+v", res) } c.poller.query <- StatQuery{res.Switch} sw := v.(SwitchStats) stat, ok := sw[res.Flow] sw[res.Flow] = res.Bytes glog.V(2).Infof("Previous stats: %+v, Now: %+v", stat, res.Bytes) if !ok || res.Bytes-stat > c.delta { glog.Infof("Found an elephent flow: %+v, %+v, %+v", res, stat, ctx.Hive().ID()) ctx.Emit(MatrixUpdate(res)) } matrix.Put(key, sw) return nil }
func (c *ofConn) Start(ctx bh.RcvContext) { defer func() { if c.driver != nil { c.driver.handleConnClose(c) } c.Close() // TODO(soheil): is there any better way to prevent deadlocks? glog.Infof("%v drains write queue for %v", ctx, c.RemoteAddr()) go c.drainWCh() }() c.ctx = ctx c.wCh = make(chan bh.Msg, ctx.Hive().Config().DataChBufSize) var err error if c.driver, err = c.handshake(); err != nil { glog.Errorf("Error in OpenFlow handshake: %v", err) return } stop := make(chan struct{}) wdone := make(chan struct{}) go c.doWrite(wdone, stop) rdone := make(chan struct{}) go c.doRead(rdone, stop) select { case <-rdone: close(stop) case <-wdone: close(stop) } <-rdone <-wdone }