Skip to content

Instantly share code, notes, and snippets.

@robbiev
Last active January 21, 2023 18:27
Show Gist options
  • Save robbiev/1854d3fc9dcb7ae884423e39f93dc1e7 to your computer and use it in GitHub Desktop.
Save robbiev/1854d3fc9dcb7ae884423e39f93dc1e7 to your computer and use it in GitHub Desktop.
select with priority in go
// SOLUTION 1
// see https://groups.google.com/forum/#!topic/golang-nuts/ChPxr_h8kUM
func maybe(b bool, c chan int) chan int {
if !b {
return nil
}
return c
}
select {
case <-maybe(val>0, p):
val--
case <-v:
val++
}
// SOLUTION 2
// see https://groups.google.com/forum/#!topic/golang-nuts/M2xjN_yWBiQ
select {
case <-higher:
foo()
default:
select {
case <-lower:
bar()
default:
...
}
}
@muir
Copy link

muir commented Aug 27, 2022

@kent-h

I'm not sure we're talking about the same problem so let's make sure of that first. I think the problem is: In a stream of events that might have gaps where there are no events, process higher priority events before processing lower priority events. Do not spin the CPU when there are no events.

Neither your code nor @robbiev 's #2 meet that criteria.

The behavior of #2 is:

  1. If there is a higher available right now then process it.
  2. If not, and there is a lower available right now then process it.
  3. If not, then exit the code (loop, function, etc)

If we put this code in a loop, it would spin the CPU when there were no events to read.

The behavior of your code is:

  1. If there is a higher available right now then process it.
  2. If not, then wait for either a higher or a lower to arrive and process whichever arrives first or pick one randomly if they both arrive at once.
  3. Then exit the code (loop, function, etc)

If we put your code in a loop, then it would only give preference to higher if there were higher waiting in the queue. That is a much weaker guarantee that what my code provides.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment