github.com/pharosnet/flyline@v1.0.2/queue_buffer.go (about)

     1  package flyline
     2  
     3  import (
     4  	"context"
     5  	"sync"
     6  	"time"
     7  )
     8  
     9  func NewQueueBuffer() Buffer {
    10  	b := new(queueBuffer)
    11  	b.seq = NewSequence()
    12  	b.sts = new(status)
    13  	b.queue = new(queue)
    14  	b.mutex = new(sync.Mutex)
    15  	b.sts.setRunning()
    16  	return b
    17  }
    18  
    19  // Queue Buffer implements Buffer.
    20  type queueBuffer struct {
    21  	sts   *status
    22  	queue *queue
    23  	seq   *Sequence
    24  	mutex *sync.Mutex
    25  }
    26  
    27  func (b *queueBuffer) Send(i interface{}) (err error) {
    28  	if b.sts.isClosed() {
    29  		err = ErrBufSendClosed
    30  		return
    31  	}
    32  	b.seq.Incr()
    33  	b.queue.add(i)
    34  	return
    35  }
    36  
    37  func (b *queueBuffer) Recv() (value interface{}, active bool) {
    38  	active = true
    39  	if b.sts.isClosed() && b.Len() == int64(0) {
    40  		active = false
    41  		return
    42  	}
    43  	value = b.queue.poll()
    44  	b.seq.Decr()
    45  	return
    46  }
    47  
    48  func (b *queueBuffer) Len() (length int64) {
    49  	length = b.seq.Get() + 1
    50  	return
    51  }
    52  
    53  func (b *queueBuffer) Close() (err error) {
    54  	b.mutex.Lock()
    55  	defer b.mutex.Unlock()
    56  	if b.sts.isClosed() {
    57  		err = ErrBufCloseClosed
    58  		return
    59  	}
    60  	b.sts.setClosed()
    61  	return
    62  }
    63  
    64  func (b *queueBuffer) Sync(ctx context.Context) (err error) {
    65  	b.mutex.Lock()
    66  	defer b.mutex.Unlock()
    67  	if b.sts.isRunning() {
    68  		err = ErrBufSyncUnclosed
    69  		return
    70  	}
    71  	for {
    72  		ok := false
    73  		select {
    74  		case <-ctx.Done():
    75  			ok = true
    76  			break
    77  		default:
    78  			if b.Len() == int64(0) {
    79  				ok = true
    80  				break
    81  			}
    82  			time.Sleep(ms500)
    83  		}
    84  		if ok {
    85  			break
    86  		}
    87  	}
    88  	return
    89  }