Skip to content

Commit a42c5dc

Browse files
committed
ch8: add exercise8.6
1 parent 4d064e1 commit a42c5dc

File tree

1 file changed

+66
-0
lines changed

1 file changed

+66
-0
lines changed

ch8/exercise8.6/main.go

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"github.com/linehk/gopl/ch5/links"
6+
"log"
7+
"os"
8+
)
9+
10+
var tokens = make(chan struct{}, 20)
11+
12+
type work struct {
13+
url string
14+
depth int
15+
}
16+
17+
func crawl(w work) []work {
18+
fmt.Printf("depth: %d, url: %s\n", w.depth, w.url)
19+
20+
if w.depth >= 3 {
21+
return nil
22+
}
23+
24+
tokens <- struct{}{} // acquire a token
25+
urls, err := links.Extract(w.url)
26+
<-tokens // release the token
27+
if err != nil {
28+
log.Print(err)
29+
}
30+
31+
var works []work
32+
for _, url := range urls {
33+
works = append(works, work{url, w.depth + 1})
34+
}
35+
return works
36+
}
37+
38+
func main() {
39+
worklist := make(chan []work)
40+
var n int // number of pending sends to worklist
41+
42+
// Start with the command-line arguments.
43+
n++
44+
go func() {
45+
var works []work
46+
for _, url := range os.Args[1:] {
47+
works = append(works, work{url, 1})
48+
}
49+
worklist <- works
50+
}()
51+
52+
// Crawl the web concurrently.
53+
seen := make(map[string]bool)
54+
for ; n > 0; n-- {
55+
works := <-worklist
56+
for _, w := range works {
57+
if !seen[w.url] {
58+
seen[w.url] = true
59+
n++
60+
go func(w work) {
61+
worklist <- crawl(w)
62+
}(w)
63+
}
64+
}
65+
}
66+
}

0 commit comments

Comments
 (0)