That is an excellent example. Thanks! On Thursday, May 24, 2018 at 8:26:36 AM UTC-7, alex....@gmail.com wrote: > > No, not the entire case statements, only the statements on the right of > the "<-" > > btw if you run it out of the playground (which makes concurrency more > deterministic) > You would get timeout sometimes and nil sometimes > > Also maybe this example would help you understand what's going on. > https://play.golang.org/p/DokMlHtdzi7 > > On Thursday, 24 May 2018 16:58:20 UTC+8, gopher...@gmail.com wrote: >> >> Thanks for the reply. >> >> So you're saying that all case statements are evaluated first before a >> choice is made. >> Which means that the full request/response must complete even if the >> timeout case finishes first. >> >> If I swap the cases, now I consistently get a `timeout`. >> All cases are run to completion, so the full request/response occurs. >> Whats the reason for selecting the timeout? shouldn't it be pseudo-random? >> https://play.golang.org/p/M-7rMPJxOWq >> >> How should the done channel be setup to get this example working properly? >> >> >> >> On Tuesday, May 22, 2018 at 5:29:43 PM UTC-7, alex....@gmail.com wrote: >>> >>> https://golang.org/ref/spec#Select_statements >>> >>> Execution of a "select" statement proceeds in several steps: >>>> >>>> 1. For all the cases in the statement, the channel operands of >>>> receive operations and the channel and right-hand-side expressions of >>>> send >>>> statements are evaluated exactly once, in source order, upon entering >>>> the >>>> "select" statement. The result is a set of channels to receive from or >>>> send >>>> to, and the corresponding values to send. Any side effects in that >>>> evaluation will occur irrespective of which (if any) communication >>>> operation is selected to proceed. Expressions on the left-hand side of >>>> a >>>> RecvStmt with a short variable declaration or assignment are not yet >>>> evaluated. >>>> 2. If one or more of the communications can proceed, a single one >>>> that can proceed is chosen via a uniform pseudo-random selection. >>>> Otherwise, if there is a default case, that case is chosen. If there is >>>> no >>>> default case, the "select" statement blocks until at least one of the >>>> communications can proceed. >>>> 3. Unless the selected case is the default case, the respective >>>> communication operation is executed. >>>> 4. If the selected case is a RecvStmt with a short variable >>>> declaration or an assignment, the left-hand side expressions are >>>> evaluated >>>> and the received value (or values) are assigned. >>>> 5. The statement list of the selected case is executed. >>>> >>>> >>> So it evaluates all your function calls before doing the select in the >>> order they appear in single threadeddly. >>> >>> On Wednesday, 23 May 2018 07:29:59 UTC+8, ag wrote: >>>> >>>> This is interesting and I still don't get why it's not working. >>>> >>>> I modified the code a bit and expected it to immediately break out of >>>> select but it still waits for http calls to finish >>>> >>>> https://play.golang.org/p/z1mmqpQtOre >>>> >>>> package main >>>> >>>> import ( >>>> "errors" >>>> "fmt" >>>> "net/http" >>>> "net/http/httptest" >>>> "time" >>>> ) >>>> >>>> func main() { >>>> ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r >>>> *http.Request) { >>>> time.Sleep(1 * time.Second) >>>> w.WriteHeader(http.StatusOK) >>>> })) >>>> defer ts.Close() >>>> >>>> req, _ := http.NewRequest(http.MethodGet, ts.URL, nil) >>>> >>>> f := func(r *http.Request, n int) error { >>>> fmt.Println("Making the http call ", n) >>>> _, err := http.DefaultClient.Do(r) >>>> return err >>>> } >>>> >>>> ch := make(chan error, 1) >>>> >>>> timeout := 1 * time.Millisecond >>>> select { >>>> case ch <- errors.New("immediate timeout"): >>>> case ch <- f(req, 1): >>>> case ch <- f(req, 2): >>>> case <-time.After(timeout): >>>> fmt.Println("Timeout being called") >>>> ch <- errors.New("timeout") >>>> } >>>> >>>> err1 := <-ch >>>> fmt.Println("Received first error", err1) >>>> close(ch) >>>> >>>> >>>> // Output: >>>> >>>> // Making the http call 1 // Making the http call 2 >>>> // Received first error immediate timeout >>>> >>>> } >>>> >>>> >>>> >>>> >>>> >>>> On Monday, May 21, 2018 at 10:25:08 PM UTC-7, Burak Serdar wrote: >>>>> >>>>> On Mon, May 21, 2018 at 12:13 PM, <gopher...@gmail.com> wrote: >>>>> > timeout := 1 * time.Millisecond >>>>> > select { >>>>> > case ch <-f(req): >>>>> > case <-time.After(timeout): >>>>> > ch <- errors.New("timeout") >>>>> > } >>>>> >>>>> The instant 'select' is evaluated, ch is writable. Also time.After() >>>>> is called, and returns a channel that will be ready to be read in a >>>>> millisecond, i.e. not readable immediately. So it'll write to ch, and >>>>> will never timeout. >>>>> >>>>> To do what you described, you need to run the request piece in a >>>>> goroutine, and write the result to a channel: >>>>> >>>>> go func() { >>>>> _,err:=http.DefaultClient.Do(...) >>>>> ch<-err >>>>> }() >>>>> >>>>> Then, wait for the error to arrive on ch, or timeout: >>>>> >>>>> select { >>>>> case err:=<-ch: >>>>> case <-time.After(timeout): >>>>> } >>>>> >>>>> >>>>> > err:= <-ch >>>>> > close(ch) >>>>> > fmt.Println(err) // outputs <nil>, not timeout >>>>> > // Output: >>>>> > // timeout >>>>> > } >>>>> > >>>>> > >>>>> > -- >>>>> > 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...@googlegroups.com. >>>>> > For more options, visit https://groups.google.com/d/optout. >>>>> >>>>
-- 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. For more options, visit https://groups.google.com/d/optout.