Use modularity / up to Exercise 1-12
[goproglang.git] / fetchall / fetchall.go
1 package fetchall
2
3 import (
4   "fmt"
5   "io"
6   // "io/ioutil"
7   "net/http"
8   "net/url"
9   "os"
10   "time"
11 )
12
13 func main() {
14   start := time.Now()
15   ch := make(chan string)
16   for _, url := range os.Args[1:] {
17     go fetch(url, ch) // start a goroutine
18   }
19   for range os.Args[1:] {
20     fmt.Println(<-ch) // receive from channel ch
21   }
22   fmt.Printf("%2.fs elapsed\n", time.Since(start).Seconds())
23 }
24 func fetch(uri string, ch chan<- string) {
25   start := time.Now()
26   resp, err := http.Get(uri)
27   if err != nil {
28     ch <- fmt.Sprint(err) // send to channel ch
29     return
30   }
31   f, err := os.Create(url.QueryEscape(uri))
32   if err != nil {
33     ch <- fmt.Sprintf("error creating file: %v", err)
34     return
35   }
36   nbytes, err := io.Copy(f, resp.Body)
37   resp.Body.Close() // dont leak resources
38   if err != nil {
39     ch <- fmt.Sprintf("while reading %s: %v", uri, err)
40     return
41   }
42   secs := time.Since(start).Seconds()
43   ch <- fmt.Sprintf("%.2fs %7d %s", secs, nbytes, uri)
44 }