github.com/niubaoshu/goutils@v0.0.0-20180828035119-e8e576f66c2b/channel.go (about) 1 package goutils 2 3 import ( 4 "sync" 5 "time" 6 ) 7 8 type Channel struct { 9 exitCh chan struct{} 10 mx sync.Mutex 11 cache []interface{} 12 cache2 []interface{} 13 fullNum int 14 FullChan chan struct{} 15 isNoticed bool 16 } 17 18 func NewChannel(fullNum int, interval time.Duration) *Channel { 19 c := &Channel{ 20 fullNum: fullNum, 21 cache: make([]interface{}, 0, fullNum*2), 22 cache2: make([]interface{}, 0, fullNum*2), 23 FullChan: make(chan struct{}), 24 exitCh: make(chan struct{}), 25 } 26 exitCh := c.exitCh 27 go func() { 28 for { 29 select { 30 case <-exitCh: 31 return 32 default: 33 time.Sleep(interval) 34 if len(c.cache) > 0 { 35 c.FullChan <- struct{}{} 36 } 37 } 38 } 39 }() 40 return c 41 } 42 43 func (c *Channel) Add(msg ...interface{}) { 44 var needNotice bool 45 c.mx.Lock() 46 c.cache = append(c.cache, msg...) 47 needNotice = len(c.cache) >= c.fullNum && !c.isNoticed 48 if needNotice { 49 c.isNoticed = true 50 } 51 c.mx.Unlock() 52 if needNotice { 53 c.FullChan <- struct{}{} 54 } 55 } 56 57 func (c *Channel) Get() (ret []interface{}) { 58 c.mx.Lock() 59 c.cache, c.cache2 = c.cache2, c.cache 60 c.cache = c.cache[:0] 61 c.isNoticed = false 62 c.mx.Unlock() 63 return c.cache2 64 } 65 66 func (c *Channel) Len() int { 67 c.mx.Lock() 68 l := len(c.cache) 69 c.mx.Unlock() 70 return l 71 } 72 73 func (c *Channel) Close() error { 74 close(c.exitCh) 75 return nil 76 }