I just tagged v1.7.0 of github.com/adrianbrad/queue, a thread-safe generic queue package. The headline feature is a new Delay queue.
What is Delay?
Delay is a priority queue where each element becomes dequeuable at a deadline computed by a caller-supplied function at Offer time. Get returns ErrNoElementsAvailable until the head is due; GetWait sleeps until it is.
type task struct {
id int
runAt time.Time
}
delayQueue := queue.NewDelay(
[]task{
{id: 1, runAt: time.Now().Add(20 * time.Millisecond)},
{id: 2, runAt: time.Now().Add(5 * time.Millisecond)},
},
func(t task) time.Time { return t.runAt },
)
// Blocks until the earliest-deadline element is due.
next := delayQueue.GetWait()
fmt.Println(next.id) // 2
Useful for retry scheduling, TTL expiry, timer wheels, and similar patterns where work should become visible at a future wall-clock time.
Implementation notes
- Min-heap by deadline, written directly on a typed slice instead of via
container/heap. pprof showedcontainer/heap'sany-boxing accounted for most of the allocations, so steady-state offer/get is now zero-alloc. -
GetWaitusessync.Cond+time.AfterFuncso "head is due" and "queue state changed" compose under a singleWait. -
Peekreturns the head regardless of whether its deadline has passed (matchesjava.util.concurrent.DelayQueue.peek).
Five queues, one interface
Delay joins Blocking, Priority, Circular, and Linked. All satisfy the same Queue[T comparable] interface, so you can swap implementations without changing call sites. The README has a small decision table for picking one.
Bonus: v1.6.0 shipped a lot
Since the last post I also tagged v1.6.0, a heavy batch of correctness and performance work:
-
Priority.MarshalJSONwas emitting elements in arbitrary heap-array order; now emits in priority order. -
Reseton Blocking, Circular, and Priority now honours capacity and zeros dropped slots (pointerTwas leaking). - Blocking switched from Signal to Broadcast, removing a fragile cascade in
PeekWait. - Linked grew an internal node free list; steady-state offer/get dropped from 16 B / 1 alloc to 0.
- Capacity validation at construction time (panics with a clear message instead of a cryptic slice panic later).
Feedback welcome
Thanks for reading.
Top comments (0)