Hacker News new | past | comments | ask | show | jobs | submit login

Also, this isn't semantically correct. In order to ensure that `conditionaA` is _always_ preferred over `conditionB`, you must also check if `conditionA` has received a value inside of `conditionB`:

    select {
    case a := <-conditionA:
        return a
    default:
    }
    select {
    case b := <-conditionB:
      case a := <-conditionA:
          return a
      default:

      return b
    default:
    }



It would be easier to discuss with a more concrete example. If I ever had to write code like the above I would reconsider the design and try to come up with something simpler.


I was also curious so I picked a likely-looking project on his github and indeed found an attempt to handle a channel "deterministically" at https://github.com/sethvargo/go-retry/blob/main/retry.go#L51

Honestly the whole first select seems redundant; any code that relies on this is broken as there's no other synchronization points to hang onto. You simply can't pretend the clock on the wall has anything to with the values transiting the program unless you introduce an actual synchronization point.

But OK, maybe you do have some strange performance case where this matters? In that case the whole thing could be more succinctly solved by looping on `for ctx.Err() == nil` instead of infinitely. Exactly as suggested at the start of the thread. (This would also likely be faster unless the context is under massive contention.)

It also leaks the timer until it fires if the context cancels, which seems like it would be more of a practical performance problem than any overhead to the additional select.




Consider applying for YC's Fall 2025 batch! Applications are open till Aug 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: