示例#1
0
//
// 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

}
示例#3
0
//
// 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
}
示例#4
0
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"))
}