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.

Reply via email to