// // evtch: // 1. 来自Zookeeper驱动通知 // 2. 该通知最终需要通过 evtbus 传递给其他人 // func (top *Topology) doWatch(evtch <-chan topo.Event, evtbus chan interface{}) { e := <-evtch // http://wiki.apache.org/hadoop/ZooKeeper/FAQ // 如何处理? 照理说不会发生的 if e.State == topo.StateExpired || e.Type == topo.EventNotWatching { log.Warnf("session expired: %+v", e) evtbus <- e return } log.Warnf("topo event %+v", e) switch e.Type { //case topo.EventNodeCreated: //case topo.EventNodeDataChanged: case topo.EventNodeChildrenChanged: //only care children changed //todo:get changed node and decode event default: // log.Warnf("%+v", e) } evtbus <- e }
// 读取Frame的完整的数据,包含 func (p *TBufferedFramedTransport) ReadFrame() (frame []byte, err error) { if p.FrameSize != 0 { err = thrift.NewTTransportExceptionFromError( fmt.Errorf("Unexpected frame size: %d", p.FrameSize)) return nil, err } var frameSize int // Reader来自transport, 中间被封装了多长 frameSize, err = p.readFrameHeader() if err != nil { err1, ok := err.(thrift.TTransportException) if ok { err = thrift.NewTTransportException(err1.TypeId(), fmt.Sprintf("Frame Header Read Error: %s", err1.Error())) } else { err = thrift.NewTTransportExceptionFromError( fmt.Errorf("Frame Header Read Error: %s", err.Error())) } return } bytes := getSlice(frameSize, frameSize) // 什么时候会出现? // 1. 如果tcp package比较大,则容易出现package的一部分先到,另一部分随后再到 // 2. 在同一个机器上的两个进程之间出现的概率低(Time Delay小); 跨机器访问,出现概率高 var l int l, err = io.ReadFull(p.Reader, bytes) // l, err = p.Reader.Read(bytes) if l != frameSize { log.Warnf(Red("<==== ReadFrame frame size: %d, Got: %d"), frameSize, l) } if err != nil { err1, ok := err.(thrift.TTransportException) if ok { err = thrift.NewTTransportException(err1.TypeId(), fmt.Sprintf("Frame Data Read Error: %s", err1.Error())) } else { err = thrift.NewTTransportExceptionFromError( fmt.Errorf("Frame Data Read Error: %s", err.Error())) } return nil, err } return bytes, nil }
// // evtch: // 1. 来自Zookeeper驱动通知 // 2. 该通知最终需要通过 evtbus 传递给其他人 // func (top *Topology) doWatch(evtch <-chan topo.Event, evtbus chan interface{}) { e := <-evtch if e.State == topo.StateExpired || e.Type == topo.EventNotWatching { log.Panicf("session expired: %+v", e) } log.Warnf("topo event %+v", e) switch e.Type { //case topo.EventNodeCreated: //case topo.EventNodeDataChanged: case topo.EventNodeChildrenChanged: //only care children changed //todo:get changed node and decode event default: // log.Warnf("%+v", e) } evtbus <- e }
func (s *Session) Serve(d Dispatcher, maxPipeline int) { var errlist errors.ErrorList defer func() { log.Infof(Red("==> Session Over: %s, Print Error List: %d Errors"), s.RemoteAddress, errlist.Len()) // 只打印第一个Error if err := errlist.First(); err != nil { log.Infof("==> Session [%p] closed, Error = %v", s, err) } else { log.Infof("==> Session [%p] closed, Quit", s) } }() // 来自connection的各种请求 tasks := make(chan *Request, maxPipeline) go func() { defer func() { // 出现错误了,直接关闭Session s.Close() // 扔掉所有的Tasks log.Warnf(Red("Session Closed, Abandon %d Tasks"), len(tasks)) for task := range tasks { task.Recycle() } }() if err := s.loopWriter(tasks); err != nil { errlist.PushBack(err) } }() defer close(tasks) // 从Client读取用户的请求,然后再交给Dispatcher来处理 if err := s.loopReader(tasks, d); err != nil { errlist.PushBack(err) } log.Info(Cyan("LoopReader Over, Session#Serve Over")) }