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 }