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  }