On Thursday, July 12, 2012, Ziad Hatahet wrote:

> Ah, you mean after repeated invocations of the containing function in case
> the timeout event keeps firing?
>

The timeout will only fire once and exit cleanly whether the value is
received or not, since the channel has a buffer of 1. The issue is that, if
the timeout is received before any values are read off c, then the three
goroutines will hang on the send operations forever (unless the program
exits, or you get a deadlock). One solution, if you know the number of
goroutines, is to put a fixed size buffer on the channel, which is just an
extra parameter for make. Another solution is to add a done channel, and
close it when you get the timeout:

   c := make(chan Result)
   done := make(chan struct{})

   // make sure done closes before function
   // exits, letting remaining goroutines exit.
   defer close(done)

  // convenience function to encapsulate pattern
  dispatch := func(f func(string)) {
       select {
       case c <- f(query):
       case <-done:  // this case becomes available once done is closed
       }
   }
   go dispatch(Web)
   go dispatch(Image)
   go dispatch(Video)

    timeout := time.After(80*time.Milliseconds)
    for len(results) < 3 {
        select {
        case result := <-c:
            results = append(results, result)
        case <- timeout:
            fmt.Println("timed out")
            return
        }
    }
    return
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to