76 lines
1.2 KiB
Go
76 lines
1.2 KiB
Go
package mqttx
|
|
|
|
import "sync"
|
|
|
|
type MessageQueue[T any] struct {
|
|
mu sync.Mutex
|
|
cond *sync.Cond
|
|
items []T
|
|
closed bool
|
|
}
|
|
|
|
func NewMessageQueue[T any]() *MessageQueue[T] {
|
|
q := &MessageQueue[T]{}
|
|
q.cond = sync.NewCond(&q.mu)
|
|
return q
|
|
}
|
|
|
|
func (q *MessageQueue[T]) Push(item T) bool {
|
|
q.mu.Lock()
|
|
defer q.mu.Unlock()
|
|
if q.closed {
|
|
return false
|
|
}
|
|
q.items = append(q.items, item)
|
|
q.cond.Signal()
|
|
return true
|
|
}
|
|
|
|
func (q *MessageQueue[T]) Pop() (T, bool) {
|
|
q.mu.Lock()
|
|
defer q.mu.Unlock()
|
|
for len(q.items) == 0 && !q.closed {
|
|
q.cond.Wait()
|
|
}
|
|
var zero T
|
|
if len(q.items) == 0 {
|
|
return zero, false
|
|
}
|
|
item := q.items[0]
|
|
q.items[0] = zero
|
|
q.items = q.items[1:]
|
|
return item, true
|
|
}
|
|
|
|
func (q *MessageQueue[T]) Drain(max int) []T {
|
|
q.mu.Lock()
|
|
defer q.mu.Unlock()
|
|
if max <= 0 || len(q.items) == 0 {
|
|
return nil
|
|
}
|
|
if max > len(q.items) {
|
|
max = len(q.items)
|
|
}
|
|
items := make([]T, max)
|
|
copy(items, q.items[:max])
|
|
var zero T
|
|
for i := 0; i < max; i++ {
|
|
q.items[i] = zero
|
|
}
|
|
q.items = q.items[max:]
|
|
return items
|
|
}
|
|
|
|
func (q *MessageQueue[T]) Len() int {
|
|
q.mu.Lock()
|
|
defer q.mu.Unlock()
|
|
return len(q.items)
|
|
}
|
|
|
|
func (q *MessageQueue[T]) Close() {
|
|
q.mu.Lock()
|
|
q.closed = true
|
|
q.mu.Unlock()
|
|
q.cond.Broadcast()
|
|
}
|