- Take a list of URLs from the
os.Stdin
. - For every URL in the list start a goroutines.
- Do not run more than
k=5
goroutines. - Do not run more than
len(URLs)
goroutines (e.g. ifk=1000
andlen(urls)=10
).
Last active
October 29, 2016 14:05
-
-
Save narqo/c0e094b0578bd95660ce96125fc807c7 to your computer and use it in GitHub Desktop.
Count the number of "Go" word in the list of URLs.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"bufio" | |
"errors" | |
"fmt" | |
"io/ioutil" | |
"net/http" | |
"os" | |
"strings" | |
"sync" | |
) | |
/* | |
$ echo -e 'https://golang.org\nhttps://golang.org\nhttps://golang.org' | go run main.go | |
Count for https://golang.org: 9 | |
Count for https://golang.org: 9 | |
Count for https://golang.org: 9 | |
Total: 27 | |
*/ | |
const ( | |
findStr = "Go" | |
maxConcurrency = 5 | |
) | |
func main() { | |
var ( | |
total int | |
wg sync.WaitGroup | |
) | |
sc := bufio.NewScanner(os.Stdin) | |
limiter := make(chan struct{}, maxConcurrency) | |
results := make(chan int) | |
for sc.Scan() { | |
limiter <- struct{}{} | |
wg.Add(1) | |
u := sc.Text() | |
go func(u string) { | |
defer func() { <-limiter }() | |
n := CountInURL(u) | |
fmt.Printf("Count for %s: %d\n", u, n) | |
results <- n | |
}(u) | |
} | |
go func() { | |
for n := range results { | |
total += n | |
wg.Done() | |
} | |
}() | |
wg.Wait() | |
fmt.Printf("Total: %d\n", total) | |
} | |
func CountInURL(u string) int { | |
body, err := getURL(u) | |
if err != nil { | |
fmt.Printf("error for %s: %v\n", u, err) | |
return 0 | |
} | |
return strings.Count(string(body), findStr) | |
} | |
func getURL(u string) ([]byte, error) { | |
if u = strings.TrimSpace(u); u == "" { | |
return nil, errors.New("empty URL") | |
} | |
resp, err := http.Get(u) | |
if err != nil { | |
return nil, err | |
} | |
defer resp.Body.Close() | |
if resp.StatusCode != http.StatusOK { | |
return nil, fmt.Errorf("bad response status: %s", resp.StatusCode) | |
} | |
return ioutil.ReadAll(resp.Body) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment