github.com/git-amp/amp-sdk-go@v0.7.5/stdlib/utils/mailbox.go (about)

     1  package utils
     2  
     3  import (
     4  	"sync"
     5  )
     6  
     7  type Mailbox struct {
     8  	chNotify chan struct{}
     9  	mu       sync.Mutex
    10  	queue    []interface{}
    11  	capacity uint64
    12  }
    13  
    14  func NewMailbox(capacity uint64) *Mailbox {
    15  	queueCap := capacity
    16  	if queueCap == 0 {
    17  		queueCap = 100
    18  	}
    19  	return &Mailbox{
    20  		chNotify: make(chan struct{}, 1),
    21  		queue:    make([]interface{}, 0, queueCap),
    22  		capacity: capacity,
    23  	}
    24  }
    25  
    26  func (m *Mailbox) Notify() chan struct{} {
    27  	return m.chNotify
    28  }
    29  
    30  func (m *Mailbox) Deliver(x interface{}) {
    31  	m.mu.Lock()
    32  	defer m.mu.Unlock()
    33  
    34  	m.queue = append([]interface{}{x}, m.queue...)
    35  	if uint64(len(m.queue)) > m.capacity && m.capacity > 0 {
    36  		m.queue = m.queue[:len(m.queue)-1]
    37  	}
    38  
    39  	select {
    40  	case m.chNotify <- struct{}{}:
    41  	default:
    42  	}
    43  }
    44  
    45  func (m *Mailbox) Retrieve() interface{} {
    46  	m.mu.Lock()
    47  	defer m.mu.Unlock()
    48  
    49  	if len(m.queue) == 0 {
    50  		return nil
    51  	}
    52  	x := m.queue[len(m.queue)-1]
    53  	m.queue = m.queue[:len(m.queue)-1]
    54  	return x
    55  }
    56  
    57  func (m *Mailbox) RetrieveAll() []interface{} {
    58  	m.mu.Lock()
    59  	defer m.mu.Unlock()
    60  	queue := m.queue
    61  	m.queue = nil
    62  	for i, j := 0, len(queue)-1; i < j; i, j = i+1, j-1 {
    63  		queue[i], queue[j] = queue[j], queue[i]
    64  	}
    65  	return queue
    66  }
    67  
    68  func (m *Mailbox) Clear() {
    69  	m.mu.Lock()
    70  	defer m.mu.Unlock()
    71  
    72  	queueCap := m.capacity
    73  	if queueCap == 0 {
    74  		queueCap = 100
    75  	}
    76  	m.queue = make([]interface{}, 0, queueCap)
    77  }