priorityq/README.md

42 lines
1.6 KiB
Markdown
Raw Normal View History

# priorityq - generic prioritized queues in Go
2023-03-01 04:33:22 +00:00
This module was inspired by [a reddit post][reddit] wherein /u/zandery23 asked
how to implement a prioritized message queue in Go. A fantastic solution was
[provided by /u/Ploobers][sol]. That's probably right for 99 out of 100 use
cases, but it's not completely precise.
2023-03-01 04:33:22 +00:00
Particularly, the second select block does not guarantee that an item from the
prioritized queue will be taken if there is also an item in the regular queue.
2023-03-01 04:33:22 +00:00
```go
select {
case job := <-mq.priorityQueue:
// ...
case job := <-mq.regularQueue:
// ...
// ...
}
```
From the [Go Language Specification][go_select]:
> If one or more of the communications can proceed, a single one that can
> proceed is chosen via a uniform pseudo-random selection.
Thus, it is possible for the second case to be chosen even if the first case is
also ready.
The `mq` package in this module implements a concurrent, prioritized message
queue that guarantees receipt of a high-priority items before low-priority
ones. This is primarily a fun exercise, I cannot recommend that anyone
actually use this in a real project.
Additionally, the root `priorityq` package implements a concurrent priority
queue, using a binary max-heap. This is more general than `mq`, because it
allows multiple levels of priority, instead of just "high" and "low". This, of
course, also makes operations slower.
2023-03-01 04:33:22 +00:00
[reddit]: https://www.reddit.com/r/golang/comments/11drc17/worker_pool_reading_from_two_channels_one_chan/
[sol]: https://www.reddit.com/r/golang/comments/11drc17/worker_pool_reading_from_two_channels_one_chan/jabfvkh/
[go_select]: https://go.dev/ref/spec#Select_statements