Skip to content

Commit 12a16f1

Browse files
committed
Some Update
1 parent 70c9dbd commit 12a16f1

File tree

19 files changed

+975
-1
lines changed

19 files changed

+975
-1
lines changed

ch01 入门/11-server1/main.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import (
88

99
func main() {
1010
http.HandleFunc("/", handler)
11-
log.Fatal(http.ListenAndServe("localhost:8000", nil))
11+
log.Fatal(http.ListenAndServe(":8000", nil))
1212
}
1313

1414
func handler(w http.ResponseWriter, r *http.Request) {

channels/worker.go

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package workers
2+
3+
type WG struct {
4+
max int
5+
allDone chan bool
6+
main chan func()
7+
}
8+
9+
func New(n int) WG {
10+
11+
procDone := make(chan bool)
12+
res := WG{
13+
allDone: make(chan bool),
14+
main: make(chan func()),
15+
}
16+
17+
for i := 0; i < n; i++ {
18+
go func() {
19+
for f := range res.main {
20+
f()
21+
}
22+
procDone <- true
23+
}()
24+
}
25+
26+
go func() {
27+
for i := 0; i < n; i++ {
28+
_ = <-procDone
29+
}
30+
res.allDone <- true
31+
32+
}()
33+
return res
34+
35+
}
36+
37+
func (wg WG) Add(f func()) {
38+
wg.main <- f
39+
}
40+
41+
//Wait, Call Once when all funcs have been added to wait for completion.
42+
//If you don't care to wait, 'go Wait' lol
43+
func (wg WG) Wait() {
44+
close(wg.main)
45+
_ = <-wg.allDone
46+
47+
}

channels/worker_test.go

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package workers
2+
3+
import (
4+
"sync"
5+
"testing"
6+
"time"
7+
)
8+
9+
func Test_Workers(t *testing.T) {
10+
wg := New(50)
11+
var l sync.Mutex
12+
p := 0
13+
14+
for i := 0; i < 1000; i++ {
15+
// fmt.Println("Adding :", i)
16+
wg.Add(func() {
17+
time.Sleep(time.Second / 10)
18+
l.Lock()
19+
p++
20+
l.Unlock()
21+
22+
})
23+
}
24+
wg.Wait()
25+
if p != 1000 {
26+
t.Log("P not reached it's goal", p)
27+
t.Fail()
28+
}
29+
30+
}

demo/decorator/compute_time.go

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package decorator
2+
3+
import (
4+
"fmt"
5+
"reflect"
6+
"runtime"
7+
"time"
8+
)
9+
10+
type SumFunc func(int64, int64) int64
11+
12+
func getFuncName(i interface{}) string {
13+
return runtime.FuncForPC(reflect.ValueOf(i).Pointer()).Name()
14+
}
15+
16+
func timedSumFunc(f SumFunc) SumFunc {
17+
return func(start, end int64) int64 {
18+
defer func(t time.Time) {
19+
fmt.Printf("--- Time Elapsed (%s): %v ---\n",
20+
getFuncName(f), time.Since(t))
21+
}(time.Now())
22+
return f(start, end)
23+
}
24+
}
25+
26+
func Sum1(start, end int64) int64 {
27+
var sum int64
28+
sum = 0
29+
if start > end {
30+
start, end = end, start
31+
}
32+
for i := start; i <= end; i++ {
33+
sum++
34+
}
35+
return sum
36+
}
37+
38+
func Sum2(start, end int64) int64 {
39+
if start > end {
40+
start, end = end, start
41+
}
42+
return (end - start + 1) * (end + start) / 2
43+
}

demo/decorator/decorator_test.go

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package decorator
2+
3+
import (
4+
"fmt"
5+
"log"
6+
"net/http"
7+
"testing"
8+
)
9+
10+
func Hello(s string) {
11+
fmt.Println(s)
12+
}
13+
func Test(t *testing.T) {
14+
15+
decorator(Hello)("Hello, World!")
16+
17+
}
18+
19+
func Test_compute(t *testing.T) {
20+
21+
sum1 := timedSumFunc(Sum1)
22+
sum2 := timedSumFunc(Sum2)
23+
fmt.Printf("%d, %d\n", sum1(-10000, 10000000), sum2(-10000, 10000000))
24+
}
25+
26+
func hello(w http.ResponseWriter, r *http.Request) {
27+
log.Printf("Recieved Request %s from %s\n", r.URL.Path, r.RemoteAddr)
28+
fmt.Fprintf(w, "Hello, World! "+r.URL.Path)
29+
}
30+
31+
func Test_http_server(t *testing.T) {
32+
http.HandleFunc("/hello", WithServerHeader(hello))
33+
err := http.ListenAndServe(":8080", nil)
34+
if err != nil {
35+
log.Fatal("ListenAndServe: ", err)
36+
}
37+
}
38+
39+
func Test_http_server_enhance(t *testing.T) {
40+
http.HandleFunc("/v4/hello", Handler(hello,
41+
WithAuthCookie, WithServerHeader, WithBasicAuth, WithDebugLog))
42+
err := http.ListenAndServe(":8080", nil)
43+
if err != nil {
44+
log.Fatal("ListenAndServe: ", err)
45+
}
46+
}

demo/decorator/hello_world.go

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package decorator
2+
3+
import "fmt"
4+
5+
func decorator(f func(s string)) func(s string) {
6+
7+
return func(s string) {
8+
fmt.Println("Started")
9+
f(s)
10+
fmt.Println("Done")
11+
}
12+
}

demo/decorator/http_server_enhance.go

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package decorator
2+
3+
import (
4+
"log"
5+
"net/http"
6+
"strings"
7+
)
8+
9+
type HttpHandlerDecorator func(http.HandlerFunc) http.HandlerFunc
10+
11+
func Handler(h http.HandlerFunc, decors ...HttpHandlerDecorator) http.HandlerFunc {
12+
for i := range decors {
13+
d := decors[len(decors)-1-i] // iterate in reverse
14+
h = d(h)
15+
}
16+
return h
17+
}
18+
19+
func WithServerHeader(h http.HandlerFunc) http.HandlerFunc {
20+
return func(w http.ResponseWriter, r *http.Request) {
21+
log.Println("--->WithServerHeader()")
22+
w.Header().Set("Server", "HelloServer v0.0.1")
23+
h(w, r)
24+
}
25+
}
26+
27+
func WithAuthCookie(h http.HandlerFunc) http.HandlerFunc {
28+
return func(w http.ResponseWriter, r *http.Request) {
29+
log.Println("--->WithAuthCookie()")
30+
cookie := &http.Cookie{Name: "Auth", Value: "Pass", Path: "/"}
31+
http.SetCookie(w, cookie)
32+
h(w, r)
33+
}
34+
}
35+
36+
func WithBasicAuth(h http.HandlerFunc) http.HandlerFunc {
37+
return func(w http.ResponseWriter, r *http.Request) {
38+
log.Println("--->WithBasicAuth()")
39+
cookie, err := r.Cookie("Auth")
40+
if err != nil || cookie.Value != "Pass" {
41+
w.WriteHeader(http.StatusForbidden)
42+
return
43+
}
44+
h(w, r)
45+
}
46+
}
47+
48+
func WithDebugLog(h http.HandlerFunc) http.HandlerFunc {
49+
return func(w http.ResponseWriter, r *http.Request) {
50+
log.Println("--->WithDebugLog")
51+
r.ParseForm()
52+
log.Println(r.Form)
53+
log.Println("path", r.URL.Path)
54+
log.Println("scheme", r.URL.Scheme)
55+
log.Println(r.Form["url_long"])
56+
for k, v := range r.Form {
57+
log.Println("key:", k)
58+
log.Println("val:", strings.Join(v, ""))
59+
}
60+
h(w, r)
61+
}
62+
}

demo/sort/sort.go

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package sort
2+
3+
import (
4+
"sort"
5+
)
6+
7+
// A couple of type definitions to make the units clear.
8+
type earthMass float64
9+
type au float64
10+
11+
// A Planet defines the properties of a solar system object.
12+
type Planet struct {
13+
name string
14+
mass earthMass
15+
distance au
16+
}
17+
18+
// By is the type of a "less" function that defines the ordering of its Planet arguments.
19+
type By func(p1, p2 *Planet) bool
20+
21+
// Sort is a method on the function type, By, that sorts the argument slice according to the function.
22+
func (by By) Sort(planets []Planet) {
23+
ps := &planetSorter{
24+
planets: planets,
25+
by: by, // The Sort method's receiver is the function (closure) that defines the sort order.
26+
}
27+
sort.Sort(ps)
28+
}
29+
30+
// planetSorter joins a By function and a slice of Planets to be sorted.
31+
type planetSorter struct {
32+
planets []Planet
33+
by func(p1, p2 *Planet) bool // Closure used in the Less method.
34+
}
35+
36+
func (s *planetSorter) Len() int { return len(s.planets) }
37+
func (s *planetSorter) Swap(i, j int) { s.planets[i], s.planets[j] = s.planets[j], s.planets[i] }
38+
func (s *planetSorter) Less(i, j int) bool { return s.by(&s.planets[i], &s.planets[j]) }
39+
40+
var planets = []Planet{
41+
{"Mercury", 0.055, 0.4},
42+
{"Venus", 0.815, 0.7},
43+
{"Earth", 1.0, 1.0},
44+
{"Mars", 0.107, 1.5},
45+
}

demo/sort/sort_test.go

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package sort
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
)
7+
8+
func Test_sort(t *testing.T) {
9+
// Closures that order the Planet structure.
10+
name := func(p1, p2 *Planet) bool {
11+
return p1.name < p2.name
12+
}
13+
mass := func(p1, p2 *Planet) bool {
14+
return p1.mass < p2.mass
15+
}
16+
distance := func(p1, p2 *Planet) bool {
17+
return p1.distance < p2.distance
18+
}
19+
decreasingDistance := func(p1, p2 *Planet) bool {
20+
return !distance(p1, p2)
21+
}
22+
23+
// Sort the planets by the various criteria.
24+
By(name).Sort(planets)
25+
fmt.Println("By name:", planets)
26+
27+
By(mass).Sort(planets)
28+
fmt.Println("By mass:", planets)
29+
30+
By(distance).Sort(planets)
31+
fmt.Println("By distance:", planets)
32+
33+
By(decreasingDistance).Sort(planets)
34+
fmt.Println("By decreasing distance:", planets)
35+
}

0 commit comments

Comments
 (0)