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.

Reply via email to