Skip to content

feat(delay): add Delay queue#61

Merged
adrianbrad merged 1 commit intomainfrom
feat/delay-queue
Apr 21, 2026
Merged

feat(delay): add Delay queue#61
adrianbrad merged 1 commit intomainfrom
feat/delay-queue

Conversation

@adrianbrad
Copy link
Copy Markdown
Owner

Summary

New Delay[T comparable] queue where each element becomes dequeuable at a deadline computed by a caller-supplied function at Offer time. Satisfies the existing Queue[T] interface — no separate interface introduced.

API

func NewDelay[T comparable](
    elems []T,
    deadlineFunc func(T) time.Time,
    opts ...Option,
) *Delay[T]

// Queue[T]: Get / Offer / Reset / Contains / Peek / Size / IsEmpty /
//            Iterator / Clear
// Extras:   GetWait / MarshalJSON

Implementation notes

  • Min-heap by deadline, written directly on []delayed[T] rather than via container/heap. pprof on the Get_Offer benchmark showed container/heap's any boxing accounted for >75% of allocations and ~50% of CPU in GC. Typed push / pop / up / down keep the steady-state offer-then-get loop at 0 allocs.
  • GetWait uses sync.Cond + time.AfterFunc so "head is due" and "state changed" compose under a single Wait, matching the cond-var idiom used by Blocking.
  • Peek returns the head regardless of whether its deadline has passed — matches java.util.concurrent.DelayQueue.peek.
  • Panics on nil deadlineFunc or negative capacity, consistent with NewPriority.

Benchmarks

BenchmarkDelayQueue/Peek          4.1 ns/op     0 B/op   0 allocs/op
BenchmarkDelayQueue/Get_Offer    52.4 ns/op     0 B/op   0 allocs/op
BenchmarkDelayQueue/Offer        63.5 ns/op   315 B/op   0 allocs/op

(B/op on Offer is amortized slice growth from unbounded pushes in the benchmark; no per-op alloc.)

Test plan

  • go test -race -shuffle=on .
  • go test -coverprofile — 100% statements
  • golangci-lint run passes locally
  • Benchmark verified with pprof (boxing eliminated)

A Queue[T comparable] implementation where each element becomes
dequeuable at a deadline computed by a caller-supplied function at
Offer time.

API:
- NewDelay(elems, deadlineFunc, opts...) — matches NewPriority's
  constructor-time func pattern.
- Queue[T] surface plus GetWait.
- MarshalJSON serialises in deadline order.

Impl:
- Min-heap by deadline, written directly on []delayed[T] rather than
  via container/heap. The container/heap Push/Pop signatures require
  boxing each element into `any`, which pprof showed as the dominant
  allocation source (>75% of allocations, ~50% of CPU spent in GC).
  Typed push/pop/up/down keeps Get+Offer steady-state at 0 allocs.
- GetWait uses sync.Cond + time.AfterFunc so "head is due" and "state
  changed" compose under a single Wait, matching the cond-var idiom
  used by Blocking.
- Peek returns the head regardless of whether its deadline has passed
  (matches java.util.concurrent.DelayQueue.peek).
- Panics on nil deadlineFunc or negative capacity, consistent with
  NewPriority.

README: new Delay Queue section with usage example; benchmark table
extended.
@codecov
Copy link
Copy Markdown

codecov bot commented Apr 21, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (5bacf9d) to head (4c2b1b6).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##              main       #61    +/-   ##
==========================================
  Coverage   100.00%   100.00%            
==========================================
  Files            5         6     +1     
  Lines          483       639   +156     
==========================================
+ Hits           483       639   +156     
Flag Coverage Δ
unittests 100.00% <100.00%> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@adrianbrad adrianbrad merged commit 999212d into main Apr 21, 2026
10 checks passed
@adrianbrad adrianbrad deleted the feat/delay-queue branch April 21, 2026 09:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant