2023-03-02 03:22:37 +00:00
|
|
|
# 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
|
2023-03-02 03:22:37 +00:00
|
|
|
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
|
2023-03-01 21:39:19 +00:00
|
|
|
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.
|
|
|
|
|
2023-03-02 03:22:37 +00:00
|
|
|
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.
|
|
|
|
|
2023-03-02 09:53:12 +00:00
|
|
|
Additionally, the `pq` 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
|