37 lines
1.3 KiB
Markdown
37 lines
1.3 KiB
Markdown
|
# priorityq - generic priority queue in Go
|
||
|
|
||
|
This module was inspired by [a reddit post][reddit] wherein /u/zandery23 asked
|
||
|
how to implement a priority 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.
|
||
|
|
||
|
Particularly, the second select block does not guarantee that an item from the
|
||
|
priority queue will be taken if there is also an item in the regular queue.
|
||
|
|
||
|
```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 `precise` package in this module implements a concurrent priority 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.
|
||
|
|
||
|
[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
|