What he's trying to say is that it is pointless to order select cases in this example, because it is impossible to guarantee ordering in an asynchronous system.
You have two asynchronous data streams, ctx.Done() and "v", in that example above. Generally, those select cases will happen one by one, as those asynchronous channels deliver data. If "v" is ready first, shortly before ctx.Done(), then v will be selected first, followed by ctx.Done(). It doesn't matter that ctx.Done() wants to be higher priority, "v" arrived first, before ctx.Done() was posted, so it's handled first. If ctx.Done() happens first, the reverse happens. The only interesting case is when both "v" and ctx.Done() are ready at the same time, which will be unlikely in practice. If ctx.Done() and "v" happen together, so that both cases of that select statement are available simultaneously, then sure, you can order them, but this will happen very infrequently, and you still MUST handle the case where "v" happens first, very close to ctx.Done(). So, if you MUST handle this case, you don't really need to bother with statement priority, since if your code is written well, this ordering won't matter. ctx.Done() might happen while you're in the middle of handling "v", for example. The desire to have priority to select statements presumes that you have several cases happen at the same time, which isn't how this will generally work. If you want to order things in a select, you have to change how it behaves, and order events within a particular time window. Say you write a poller which samples the event queue every second. If you do this, then sure, you can order things however you want, but the cost you pay is that second of buffering latency. On Fri, Oct 4, 2019 at 1:19 PM T L <tapir....@gmail.com> wrote: > > > On Friday, October 4, 2019 at 4:09:09 PM UTC-4, Robert Engels wrote: >> >> Because ctx.Done() and v being ready for read are independent events. You >> can not impose ordering on them unless there is an outer mutex that both >> events are subject to. >> >> As an aside, this is why I think the best 'concurrent software' >> developers are those that have been exposed to at least some hardware >> design. Many programmers think in terms of 1 and 0 and everything being >> ordered. This is certainly not the case in hardware, nor concurrent >> software. (For example, in computer hardware, the clock/sync line is what >> is used as the outer controlling event, but still things like propagation >> times, etc. make even this simple statement not fully correct). >> >> > Still not understanding what you new saying. ;D > > Again, select case priority enables use to deduce two select cases > to one select case in coding in many scenarios. > This often leads to cleaner code, avoid can avoid the harm caused > by missing a try-receive select case. > > > >> -----Original Message----- >> From: T L >> Sent: Oct 4, 2019 2:44 PM >> To: golang-nuts >> Subject: Re: [go-nuts] Re: An old problem: lack of priority select cases >> >> >> >> On Friday, October 4, 2019 at 3:32:31 PM UTC-4, Robert Engels wrote: >>> >>> You still are not understanding proper concurrent design. Priority >>> select cases do not matter in the case of asynchronous external events. >>> >> >> It at least avoids code verbosity and improves code quantity.. >> >> BTW, I don't understand what you said. Could you elaborate more? >> >> >>> On Oct 4, 2019, at 1:46 PM, T L <tapi...@gmail.com> wrote: >>> >>> >>> I just found an example in the "context" package docs: >>> >>> // // Stream generates values with DoSomething and sends them to out >>> // // until DoSomething returns an error or ctx.Done is closed. >>> // func Stream(ctx context.Context, out chan<- Value) error { >>> // for { >>> // v, err := DoSomething(ctx) >>> // if err != nil { >>> // return err >>> // } >>> // select { >>> // case <-ctx.Done(): >>> // return ctx.Err() >>> // case out <- v: >>> // } >>> // } >>> // } >>> >>> It looks the send "out <- v" still has a possibility to be executed, >>> even if "ctx.Done()" is closed. >>> But if Go supports select case priority, then this will never happen. >>> >>> >>> >>> On Wednesday, August 28, 2019 at 12:06:33 PM UTC-4, T L wrote: >>>> >>>> The old thread: >>>> https://groups.google.com/forum/#!topic/golang-nuts/ZrVIhHCrR9o >>>> >>>> Go channels are flexible, but in practice, I often encountered some >>>> situations in which channel are hard to use. >>>> Given an example: >>>> >>>> import "math/rand" >>>> >>>> type Producer struct { >>>> data chan int >>>> closed chan struct{} >>>> } >>>> >>>> func NewProducer() *Producer { >>>> p := &Producer { >>>> data: make(chan int), >>>> closed: make(chan struct{}), >>>> } >>>> >>>> go p.run() >>>> >>>> return p >>>> } >>>> >>>> func (p *Produce) Stream() chan int { >>>> return p.data >>>> } >>>> >>>> func (p *Producer) run() { >>>> for { >>>> // If non-blocking cases are selected by their appearance order, >>>> // then the following slect block is a perfect use. >>>> select { >>>> case(0) <-p.closed: return >>>> case p.data <- rand.Int(): >>>> } >>>> } >>>> } >>>> >>>> func (p *Produce) Clsoe() { >>>> close(p.closed) >>>> close(p.data) >>>> } >>>> >>>> func main() { >>>> p := NewProducer() >>>> for n := p.Stream() { >>>> // use n ... >>>> } >>>> } >>>> >>>> >>>> If the first case in the select block in the above example has a higher >>>> priority than the second one, >>>> then coding will be much happier for the use cases like the above one. >>>> >>>> In short, the above use case requires: >>>> * for receivers, data streaming end is notified by the close of a >>>> channel. >>>> * for senders, data will never be sent to closed channel. >>>> >>>> But, as Go 1 doesn't support priority select cases, it is much tedious >>>> to implement the code >>>> satisfying the above listed requirements. The final implementation is >>>> often very ugly and inefficient. >>>> >>>> Does anyone else also experience the pain? >>>> >>> -- >>> You received this message because you are subscribed to the Google >>> Groups "golang-nuts" group. >>> To unsubscribe from this group and stop receiving emails from it, send >>> an email to golan...@googlegroups.com. >>> To view this discussion on the web visit >>> https://groups.google.com/d/msgid/golang-nuts/b7a14153-253e-43c4-bda5-96079601465f%40googlegroups.com >>> <https://groups.google.com/d/msgid/golang-nuts/b7a14153-253e-43c4-bda5-96079601465f%40googlegroups.com?utm_medium=email&utm_source=footer> >>> . >>> >>> -- >> You received this message because you are subscribed to the Google Groups >> "golang-nuts" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to golan...@googlegroups.com. >> To view this discussion on the web visit >> https://groups.google.com/d/msgid/golang-nuts/77fca2e9-120d-45e0-8ae9-5d24b63827bd%40googlegroups.com >> <https://groups.google.com/d/msgid/golang-nuts/77fca2e9-120d-45e0-8ae9-5d24b63827bd%40googlegroups.com?utm_medium=email&utm_source=footer> >> . >> >> >> >> >> -- > You received this message because you are subscribed to the Google Groups > "golang-nuts" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to golang-nuts+unsubscr...@googlegroups.com. > To view this discussion on the web visit > https://groups.google.com/d/msgid/golang-nuts/cf695058-93ce-4b81-99d0-3c622a63202a%40googlegroups.com > <https://groups.google.com/d/msgid/golang-nuts/cf695058-93ce-4b81-99d0-3c622a63202a%40googlegroups.com?utm_medium=email&utm_source=footer> > . > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/CA%2Bv29LumVzpKW89W-kKf9NfXwBBij5ZUUf3MCeCAyiAER6T%2BwQ%40mail.gmail.com.