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() }