package stat import ( "container/list" "fmt" "github.com/TransX/log" "github.com/TransX/model" "sync" ) var mux sync.Mutex type TunnelStatusManager struct { // mux sync.Mutex tunnelList *list.List regChan chan interface{} unregChan chan interface{} } func NewTunnelStatusManager() *TunnelStatusManager { t := new(TunnelStatusManager) t.regChan = make(chan interface{}) t.unregChan = make(chan interface{}) t.tunnelList = new(list.List) go t.chanListener() return t } func (this *TunnelStatusManager) GetRegChan() chan interface{} { return this.regChan } func (this *TunnelStatusManager) GetUnregChan() chan interface{} { return this.unregChan } func (this *TunnelStatusManager) register(t interface{}) { // this.mux.Lock() // defer this.mux.Unlock() mux.Lock() defer mux.Unlock() this.tunnelList.PushBack(t) l := this.tunnelList // c := 0 // for e := l.Front(); e != nil; e = e.Next() { // c++ // if c > l.Len() { // log.Error("out of bound of list") // } // if e.Value == nil { // log.Debug("a nil len of list %d c %d", l.Len(), c) // back := l.Back() // if back == nil { // log.Debug("back is nill") // } // } // } m := t.(*model.Tunnel) log.Info("tunnel %s registerd len %d", m.GetID(), l.Len()) } func (this *TunnelStatusManager) unregister(t interface{}) { // this.mux.Lock() // defer this.mux.Unlock() mux.Lock() defer mux.Unlock() l := this.tunnelList log.Debug("%d tunnels before remove.", this.tunnelList.Len()) // n := 0 nl := new(list.List) // tn := "" for e := l.Front(); e != nil; e = e.Next() { if e.Value != t { // log.Debug("Found") // l.Remove(e) // break // n++ nl.PushBack(e.Value) // en := 0 // for ee := nl.Front(); ee != nil; ee = ee.Next() { // en++ // } // if en > nl.Len() { // log.Error("en > ee") // } // v := e.Value // if v == nil { // continue // } // m_ := v.(*model.Tunnel) // tn = tn + m_.GetID() } } // log.Debug("display tunnels %s", tn) // if n == this.tunnelList.Len() { // m := t.(*model.Tunnel) // log.Debug("check tunntel %s", m.GetID()) // } this.tunnelList = nl log.Debug("%d tunnels after remove.", this.tunnelList.Len()) } func (this *TunnelStatusManager) chanListener() { for { select { case r := <-this.regChan: this.register(r) m := r.(*model.Tunnel) log.Debug("A tunnel registered id %s", m.GetID()) log.Debug(this.QueryStatString()) case ur := <-this.unregChan: this.unregister(ur) m := ur.(*model.Tunnel) log.Debug("A tunnel unregistered id %s", m.GetID()) } } } func (this *TunnelStatusManager) QueryStatString() string { // this.mux.Lock() // defer this.mux.Unlock() mux.Lock() defer mux.Unlock() return fmt.Sprintf("There %d tunnels running.\n", this.tunnelList.Len()) }