github.com/zhongdalu/gf@v1.0.0/g/container/gchan/gchan.go (about) 1 // Copyright 2017 gf Author(https://github.com/zhongdalu/gf). All Rights Reserved. 2 // 3 // This Source Code Form is subject to the terms of the MIT License. 4 // If a copy of the MIT was not distributed with this file, 5 // You can obtain one at https://github.com/zhongdalu/gf. 6 7 // Package gchan provides graceful channel for no panic operations. 8 // 9 // It's safe to call Chan.Push/Close functions repeatedly. 10 package gchan 11 12 import ( 13 "errors" 14 15 "github.com/zhongdalu/gf/g/container/gtype" 16 ) 17 18 // Graceful channel. 19 type Chan struct { 20 channel chan interface{} 21 closed *gtype.Bool 22 } 23 24 // New creates a graceful channel with given <limit>. 25 func New(limit int) *Chan { 26 return &Chan{ 27 channel: make(chan interface{}, limit), 28 closed: gtype.NewBool(), 29 } 30 } 31 32 // Push pushes <value> to channel. 33 // It is safe to be called repeatedly. 34 func (c *Chan) Push(value interface{}) error { 35 if c.closed.Val() { 36 return errors.New("channel is closed") 37 } 38 c.channel <- value 39 return nil 40 } 41 42 // Pop pops value from channel. 43 // If there's no value in channel, it would block to wait. 44 // If the channel is closed, it will return a nil value immediately. 45 func (c *Chan) Pop() interface{} { 46 return <-c.channel 47 } 48 49 // Close closes the channel. 50 // It is safe to be called repeatedly. 51 func (c *Chan) Close() { 52 if !c.closed.Set(true) { 53 close(c.channel) 54 } 55 } 56 57 // See Len. 58 func (c *Chan) Size() int { 59 return c.Len() 60 } 61 62 // Len returns the length of the channel. 63 func (c *Chan) Len() int { 64 return len(c.channel) 65 } 66 67 // Cap returns the capacity of the channel. 68 func (c *Chan) Cap() int { 69 return cap(c.channel) 70 }