├── 10 └── docker-k8s.pdf ├── 11 └── flow_based_programming.pdf ├── 12 ├── error handling.pdf └── go-internals │ ├── .gitignore │ ├── LICENSE │ ├── README.md │ ├── code │ ├── chan.go │ ├── interface.go │ ├── map.go │ ├── nil-1.go │ ├── nil-2.go │ ├── slice.go │ └── sync_map.go │ ├── go-internals.slide │ └── image │ ├── chan-1.png │ ├── interfacetype.png │ ├── itab.png │ ├── map-2.png │ ├── map-3.png │ ├── map.png │ ├── runtime-hacking.png │ ├── runtime.png │ ├── slice-2.png │ ├── slice.png │ ├── sync_map-1.png │ ├── sync_map.png │ ├── sync_map_load.png │ ├── sync_map_store.png │ └── type.png ├── 13 ├── go-db │ ├── README.md │ ├── code │ │ ├── advanceQuery.go │ │ ├── batchInsert.go │ │ ├── databaseSQLCore │ │ │ ├── driver.go │ │ │ └── sql.go │ │ ├── driverHook.go │ │ ├── drivers │ │ │ └── mysql │ │ │ │ └── driver.go │ │ ├── lastInsertID.go │ │ ├── normalQuery.go │ │ └── ping.go │ ├── godb.slide │ ├── images │ │ ├── cycleProcess.png │ │ ├── driverAndCore.png │ │ ├── fun.jpeg │ │ ├── galera.png │ │ ├── galeraFail.png │ │ ├── getConnActivities.png │ │ ├── gomysql.png │ │ └── initializeDBObj.png │ └── runslide.sh ├── go-synthesis │ └── Sound synthesis w Golang.pdf └── goa │ ├── beach.jpg │ ├── clean.jpg │ ├── deps_after.png │ ├── deps_before.png │ ├── doc.md │ ├── goa.slide │ ├── init.go │ ├── init2.go │ ├── mvc.svg │ ├── qr.jpg │ ├── routes.go │ ├── subtemplates.go │ └── swagger.yaml ├── 14 └── grpc │ ├── README.md │ ├── bench │ ├── multi │ │ ├── grpcWithETCD │ │ │ ├── client │ │ │ │ ├── app.go │ │ │ │ ├── common.pb.go │ │ │ │ └── vendor.conf │ │ │ ├── protos │ │ │ │ ├── common.pb.go │ │ │ │ ├── common.proto │ │ │ │ └── gen.sh │ │ │ ├── server1 │ │ │ │ ├── app.go │ │ │ │ ├── common.pb.go │ │ │ │ └── vendor.conf │ │ │ └── server2 │ │ │ │ ├── app.go │ │ │ │ ├── common.pb.go │ │ │ │ └── vendor.conf │ │ ├── grpcWithNginx │ │ │ ├── client │ │ │ │ ├── app.go │ │ │ │ └── common.pb.go │ │ │ ├── protos │ │ │ │ ├── common.pb.go │ │ │ │ ├── common.proto │ │ │ │ └── gen.sh │ │ │ ├── server1 │ │ │ │ ├── app.go │ │ │ │ ├── common.pb.go │ │ │ │ └── vendor.conf │ │ │ └── server2 │ │ │ │ ├── app.go │ │ │ │ ├── common.pb.go │ │ │ │ └── vendor.conf │ │ ├── json │ │ │ ├── client │ │ │ │ └── app.go │ │ │ ├── server1 │ │ │ │ ├── app.go │ │ │ │ └── vendor.conf │ │ │ └── server2 │ │ │ │ ├── app.go │ │ │ │ └── vendor.conf │ │ └── protobuf │ │ │ ├── client │ │ │ ├── app.go │ │ │ ├── common.pb.go │ │ │ └── vendor.conf │ │ │ ├── protos │ │ │ ├── common.pb.go │ │ │ ├── common.proto │ │ │ └── gen.sh │ │ │ ├── server1 │ │ │ ├── app.go │ │ │ ├── common.pb.go │ │ │ └── vendor.conf │ │ │ └── server2 │ │ │ ├── app.go │ │ │ ├── common.pb.go │ │ │ └── vendor.conf │ └── single │ │ ├── grpc │ │ ├── client │ │ │ ├── app.go │ │ │ └── common.pb.go │ │ ├── protos │ │ │ ├── common.pb.go │ │ │ ├── common.proto │ │ │ └── gen.sh │ │ └── server │ │ │ ├── app.go │ │ │ ├── common.pb.go │ │ │ └── vendor.conf │ │ ├── json │ │ ├── client │ │ │ └── app.go │ │ └── server │ │ │ ├── app.go │ │ │ └── vendor.conf │ │ └── protobuf │ │ ├── client │ │ ├── app.go │ │ ├── common.pb.go │ │ └── vendor.conf │ │ ├── protos │ │ ├── common.pb.go │ │ ├── common.proto │ │ └── gen.sh │ │ └── server │ │ ├── app.go │ │ ├── common.pb.go │ │ └── vendor.conf │ ├── grpc.slide │ ├── images │ ├── b1.png │ ├── b2.png │ ├── b3.png │ ├── browndrink.jpg │ ├── clientlb.png │ ├── clientside.png │ ├── grpclogo.png │ ├── http2.svg │ ├── ipc.png │ ├── lbproxy.png │ ├── ms.png │ ├── pubsub.png │ ├── rest.png │ ├── serverside.png │ ├── srvdiscovery1.png │ ├── stream.svg │ ├── team.png │ ├── think.jpg │ └── usecase.png │ └── runslide.sh ├── 15 ├── _race │ ├── README.MD │ ├── code │ │ ├── example1.go │ │ ├── example2.go │ │ └── example3.go │ ├── images │ │ ├── race1.png │ │ └── race2.jpg │ ├── misc │ │ ├── example2.result.txt │ │ └── race_detector.sh │ └── race.slide └── code_generator │ ├── Code generator.pdf │ └── examples │ ├── ast │ ├── example.go │ └── main.go │ └── stringer │ ├── enum │ ├── enum.go │ └── gen.go │ └── main.go ├── .gitignore ├── 01 ├── Golang in real work.pdf ├── Why go.pdf └── intro.pdf ├── 02 ├── Concurrency in Go.pdf └── nvcnvn-sharing.pdf ├── 04 ├── golang at lozi.pdf └── intro.pdf ├── 05 ├── to-go-or-not-to-go.pdf └── vim_as_go_editor.pdf ├── 06 ├── DevOps.chotot.vn.pdf ├── Overview.-.Embedded.Software.with.Golang.pdf └── go_1_6.pdf ├── 07 ├── RocketIt.pdf ├── git-best-practices.png ├── git-best-practices.webarchive └── of-go-template-and-typesafety.zip ├── 09 ├── Machine Learning in GO.pdf ├── info ├── pic │ ├── IMG_0241.JPG │ ├── IMG_0242.JPG │ ├── IMG_0246.JPG │ ├── IMG_0247.JPG │ ├── IMG_0252.JPG │ ├── IMG_0263.JPG │ ├── IMG_0265.JPG │ └── IMG_0267.JPG ├── pic_anhht │ ├── IMG_0220.JPG │ ├── IMG_0221.JPG │ ├── IMG_0222.JPG │ ├── IMG_0223.JPG │ ├── IMG_0224.JPG │ ├── IMG_0226.JPG │ ├── IMG_0227.JPG │ ├── IMG_0228.JPG │ ├── IMG_0229.JPG │ ├── IMG_0230.JPG │ ├── IMG_0231.JPG │ ├── IMG_0232.JPG │ ├── IMG_0233.JPG │ └── IMG_0234.JPG └── sql-orm-in-golang.pdf ├── 17-VN-gophers-after-COVID ├── effectivego │ ├── README.md │ ├── example │ │ ├── assertion │ │ │ ├── notok.go │ │ │ └── ok.go │ │ ├── conversion │ │ │ └── notmatch.go │ │ ├── function │ │ │ ├── addinvoice.go │ │ │ ├── addquote.go │ │ │ ├── addrequestion.go │ │ │ ├── addtransaction.go │ │ │ ├── bad.go │ │ │ ├── better.go │ │ │ ├── betterreturn.go │ │ │ ├── good.go │ │ │ ├── passbool.go │ │ │ ├── returnfirst.go │ │ │ └── switch.go │ │ ├── map │ │ │ └── assertion.go │ │ └── return │ │ │ ├── bad.go │ │ │ └── good.go │ ├── image │ │ ├── baddocfunction.png │ │ ├── goodautocomplete.png │ │ └── typingfunction.png │ └── present.slide └── microservices-in-action │ └── Microservices In Action - The Funzy Dev.pdf ├── 2016_04_12_HaNoi_TechTalk ├── Build Command Line Tool with Golang.pdf ├── Go at FSoft.pdf ├── Struct tags in Go.pdf ├── Use Queue to scale server performance.pdf └── What do people say when they switch to Go.pdf ├── README.md ├── go-installfest └── Go Installfest.pdf ├── images └── cover.jpg ├── logo.png ├── logo.sketch └── template ├── template_01.key └── template_01.pptx /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_store 2 | **/vendor 3 | 4 | tags 5 | -------------------------------------------------------------------------------- /01/Golang in real work.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/01/Golang in real work.pdf -------------------------------------------------------------------------------- /01/Why go.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/01/Why go.pdf -------------------------------------------------------------------------------- /01/intro.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/01/intro.pdf -------------------------------------------------------------------------------- /02/Concurrency in Go.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/02/Concurrency in Go.pdf -------------------------------------------------------------------------------- /02/nvcnvn-sharing.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/02/nvcnvn-sharing.pdf -------------------------------------------------------------------------------- /04/golang at lozi.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/04/golang at lozi.pdf -------------------------------------------------------------------------------- /04/intro.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/04/intro.pdf -------------------------------------------------------------------------------- /05/to-go-or-not-to-go.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/05/to-go-or-not-to-go.pdf -------------------------------------------------------------------------------- /05/vim_as_go_editor.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/05/vim_as_go_editor.pdf -------------------------------------------------------------------------------- /06/DevOps.chotot.vn.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/06/DevOps.chotot.vn.pdf -------------------------------------------------------------------------------- /06/Overview.-.Embedded.Software.with.Golang.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/06/Overview.-.Embedded.Software.with.Golang.pdf -------------------------------------------------------------------------------- /06/go_1_6.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/06/go_1_6.pdf -------------------------------------------------------------------------------- /07/RocketIt.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/07/RocketIt.pdf -------------------------------------------------------------------------------- /07/git-best-practices.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/07/git-best-practices.png -------------------------------------------------------------------------------- /07/git-best-practices.webarchive: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/07/git-best-practices.webarchive -------------------------------------------------------------------------------- /07/of-go-template-and-typesafety.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/07/of-go-template-and-typesafety.zip -------------------------------------------------------------------------------- /09/Machine Learning in GO.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/09/Machine Learning in GO.pdf -------------------------------------------------------------------------------- /09/info: -------------------------------------------------------------------------------- 1 | - Event: https://www.facebook.com/events/1732755943712433/ 2 | -------------------------------------------------------------------------------- /09/pic/IMG_0241.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/09/pic/IMG_0241.JPG -------------------------------------------------------------------------------- /09/pic/IMG_0242.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/09/pic/IMG_0242.JPG -------------------------------------------------------------------------------- /09/pic/IMG_0246.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/09/pic/IMG_0246.JPG -------------------------------------------------------------------------------- /09/pic/IMG_0247.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/09/pic/IMG_0247.JPG -------------------------------------------------------------------------------- /09/pic/IMG_0252.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/09/pic/IMG_0252.JPG -------------------------------------------------------------------------------- /09/pic/IMG_0263.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/09/pic/IMG_0263.JPG -------------------------------------------------------------------------------- /09/pic/IMG_0265.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/09/pic/IMG_0265.JPG -------------------------------------------------------------------------------- /09/pic/IMG_0267.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/09/pic/IMG_0267.JPG -------------------------------------------------------------------------------- /09/pic_anhht/IMG_0220.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/09/pic_anhht/IMG_0220.JPG -------------------------------------------------------------------------------- /09/pic_anhht/IMG_0221.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/09/pic_anhht/IMG_0221.JPG -------------------------------------------------------------------------------- /09/pic_anhht/IMG_0222.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/09/pic_anhht/IMG_0222.JPG -------------------------------------------------------------------------------- /09/pic_anhht/IMG_0223.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/09/pic_anhht/IMG_0223.JPG -------------------------------------------------------------------------------- /09/pic_anhht/IMG_0224.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/09/pic_anhht/IMG_0224.JPG -------------------------------------------------------------------------------- /09/pic_anhht/IMG_0226.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/09/pic_anhht/IMG_0226.JPG -------------------------------------------------------------------------------- /09/pic_anhht/IMG_0227.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/09/pic_anhht/IMG_0227.JPG -------------------------------------------------------------------------------- /09/pic_anhht/IMG_0228.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/09/pic_anhht/IMG_0228.JPG -------------------------------------------------------------------------------- /09/pic_anhht/IMG_0229.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/09/pic_anhht/IMG_0229.JPG -------------------------------------------------------------------------------- /09/pic_anhht/IMG_0230.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/09/pic_anhht/IMG_0230.JPG -------------------------------------------------------------------------------- /09/pic_anhht/IMG_0231.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/09/pic_anhht/IMG_0231.JPG -------------------------------------------------------------------------------- /09/pic_anhht/IMG_0232.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/09/pic_anhht/IMG_0232.JPG -------------------------------------------------------------------------------- /09/pic_anhht/IMG_0233.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/09/pic_anhht/IMG_0233.JPG -------------------------------------------------------------------------------- /09/pic_anhht/IMG_0234.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/09/pic_anhht/IMG_0234.JPG -------------------------------------------------------------------------------- /09/sql-orm-in-golang.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/09/sql-orm-in-golang.pdf -------------------------------------------------------------------------------- /10/docker-k8s.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/10/docker-k8s.pdf -------------------------------------------------------------------------------- /11/flow_based_programming.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/11/flow_based_programming.pdf -------------------------------------------------------------------------------- /12/error handling.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/12/error handling.pdf -------------------------------------------------------------------------------- /12/go-internals/.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.dll 4 | *.so 5 | *.dylib 6 | 7 | # Test binary, build with `go test -c` 8 | *.test 9 | 10 | # Output of the go coverage tool, specifically when used with LiteIDE 11 | *.out 12 | 13 | # Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736 14 | .glide/ 15 | .DS_Store 16 | -------------------------------------------------------------------------------- /12/go-internals/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Tam Nguyen Duc 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /12/go-internals/README.md: -------------------------------------------------------------------------------- 1 | # go-internals 2 | 3 | Slides for Golang Vietnam Meetup #12 4 | -------------------------------------------------------------------------------- /12/go-internals/code/chan.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | // This `ping` function only accepts a channel for sending 6 | // values. It would be a compile-time error to try to 7 | // receive on this channel. 8 | func ping(pings chan<- string, msg string) { 9 | pings <- msg 10 | } 11 | 12 | // The `pong` function accepts one channel for receives 13 | // (`pings`) and a second for sends (`pongs`). 14 | func pong(pings <-chan string, pongs chan<- string) { 15 | msg := <-pings 16 | pongs <- msg 17 | } 18 | 19 | func main() { 20 | pings := make(chan string, 1) 21 | pongs := make(chan string, 1) 22 | ping(pings, "passed message") 23 | pong(pings, pongs) 24 | fmt.Println(<-pongs) 25 | } 26 | -------------------------------------------------------------------------------- /12/go-internals/code/interface.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | type I interface { 6 | M() string 7 | } 8 | type T struct { 9 | name string 10 | } 11 | 12 | func (t T) M() string { 13 | return t.name 14 | } 15 | func Hello(i I) { 16 | fmt.Printf("Hi, my name is %s\n", i.M()) 17 | } 18 | func main() { 19 | Hello(T{name: "Jon Snow"}) 20 | } 21 | -------------------------------------------------------------------------------- /12/go-internals/code/map.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | commits := map[string]int{ 7 | "rsc": 3711, 8 | "r": 2138, 9 | "gri": 1908, 10 | "adg": 912, 11 | } 12 | 13 | for key, value := range commits { 14 | fmt.Println("Key:", key, "Value:", value) 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /12/go-internals/code/nil-1.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | ) 7 | 8 | func main() { 9 | // println(nil) // 1 10 | println(interface{}(nil)) // 2 11 | fmt.Println(nil) // 3 12 | // println(interface{}(nil) == (*int)(nil)) // 4 13 | println(nil == error((*os.PathError)(nil))) // 5 14 | } 15 | -------------------------------------------------------------------------------- /12/go-internals/code/nil-2.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | fmt.Printf("Func type nil:%#v\n", (func())(nil)) 7 | fmt.Printf("Map type nil:%#v\n", map[string]string(nil)) 8 | fmt.Printf("Slice type nil:%#v\n", []string(nil)) 9 | fmt.Printf("Interface{} type nil:%#v\n", nil) 10 | fmt.Printf("Channel type nil:%#v\n", (chan struct{})(nil)) 11 | fmt.Printf("Pointer type nil:%#v\n", (*struct{})(nil)) 12 | fmt.Printf("Pointer type nil:%#v\n", (*int)(nil)) 13 | } 14 | -------------------------------------------------------------------------------- /12/go-internals/code/slice.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | s1 := make([]int, 3, 4) 7 | copy(s1, []int{1, 2, 3}) 8 | fmt.Println(len(s1), cap(s1), &s1[0]) 9 | 10 | s1 = append(s1, 4) 11 | fmt.Println(len(s1), cap(s1), &s1[0]) 12 | 13 | s2 := s1[1:] 14 | fmt.Println(len(s2), cap(s2), &s2[0]) 15 | 16 | s1 = append(s1, 5) 17 | fmt.Println(len(s1), cap(s1), &s1[0]) 18 | } 19 | -------------------------------------------------------------------------------- /12/go-internals/code/sync_map.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "sync" 6 | "time" 7 | ) 8 | 9 | // START OMIT 10 | func main() { 11 | var m sync.Map 12 | 13 | for i := 0; i < 3; i++ { 14 | go func(i int) { 15 | for j := 0; ; j++ { 16 | m.Store(i, j) 17 | } 18 | }(i) 19 | } 20 | 21 | for i := 0; i < 10; i++ { 22 | m.Range(func(key, value interface{}) bool { 23 | fmt.Printf("%d: %d\t", key, value) 24 | return true 25 | }) 26 | fmt.Println() 27 | time.Sleep(time.Second) 28 | } 29 | } 30 | 31 | // END OMIT 32 | -------------------------------------------------------------------------------- /12/go-internals/go-internals.slide: -------------------------------------------------------------------------------- 1 | Go internals 2 | An invitation to golang/go source code 3 | 6 Sep 2017 4 | 5 | Nguyen Duc Tam 6 | Anduin Transactions 7 | @gopher 8 | 9 | * Data structures and data types 10 | 11 | * Nil 12 | 13 | .play code/nil-1.go 14 | 15 | - _nil_ is a typed value 16 | - "... unless the value is the predeclared identifier nil, which has no type" - Go specification 17 | - _nil_ differs if their types differ 18 | 19 | .link https://golang.org/doc/faq#nil_error Why is my nil error value not equal to nil? 20 | 21 | * Nil (2) 22 | 23 | .play code/nil-2.go 24 | 25 | "Nil is a predeclared identifier representing the zero value for a pointer, channel, func, interface, map, or slice types." - Go doc "builtin" package 26 | 27 | .link https://speakerdeck.com/campoy/understanding-nil Understanding Nil (slides) 28 | .link https://www.gmarik.info/blog/2016/understanding-golang-nil-value/ Understanding Golang nil value (blog) 29 | 30 | * Slices 31 | 32 | .play code/slice.go 33 | 34 | * Slices 35 | 36 | .image image/slice.png _ 500 37 | 38 | There are _3_ components of slice: 39 | - *Pointer*: Point to the start position of slice in the underlying array 40 | - *length* : the number of elements referred to by the slice 41 | - *capacity*: the number of elements in the underlying array 42 | 43 | * Bonus: How "append()" works? 44 | 45 | .link https://github.com/golang/go/blob/master/src/runtime/slice.go#L82 slice.go#L82 46 | 47 | .image image/slice-2.png 600 _ 48 | 49 | * Maps 50 | 51 | .play code/map.go 52 | 53 | * Maps (2) 54 | 55 | .link http://github.com/golang/go/blob/master/src/runtime/hashmap.go hashmap.go 56 | 57 | .image image/map.png 480 _ 58 | 59 | * Inside a map 60 | 61 | Maps in Go are implemented as a hash table. 62 | 63 | - The hash table is structured as an array of buckets 64 | - The number of buckets is always a power of 2 65 | - A hash key is generated, the low order orbits (LOB) of the generated hash key is used to select a bucket 66 | 67 | .image https://www.goinggo.net/images/goinggo/Screen+Shot+2013-12-31+at+6.35.43+PM.png 100 _ 68 | 69 | * Inside a map (2) 70 | 71 | - There is an array with the top 8 high order bits (HOB) 72 | - This array distinguishes each individual key/value pair 73 | - There is an array of bytes that store the key/value pairs 74 | - Key and value are packed together 75 | 76 | .image https://www.goinggo.net/images/goinggo/Screen+Shot+2013-12-31+at+7.01.15+PM.png 360 _ 77 | 78 | * How maps grow 79 | A bucket stores only 8 key/value pair. If a new key is added, an overflow bucket is created. 80 | 81 | .image https://www.goinggo.net/images/goinggo/Screen+Shot+2013-12-31+at+7.12.06+PM.png 120 _ 82 | 83 | .image image/map-3.png 300 _ 84 | 85 | * sync.Map (Go 1.9) 86 | 87 | .link https://github.com/golang/go/issues/18177 sync: add a Map to replace RWLock+map usage 88 | 89 | .play code/sync_map.go /START OMIT/,/END OMIT/ 90 | 91 | * Inside sync.Map 92 | 93 | .image image/sync_map-1.png _ 800 94 | 95 | * sync.Map.Load 96 | 97 | .image image/sync_map_load.png _ 1000 98 | 99 | * sync.Map.Store 100 | 101 | .image image/sync_map_store.png _ 1000 102 | 103 | * Interfaces 104 | 105 | .play code/interface.go 106 | 107 | * Inside an interface 108 | 109 | .image image/itab.png _ 1000 110 | 111 | .image image/interfacetype.png _ 1000 112 | 113 | * Inside an interface (2) 114 | 115 | .image image/type.png _ 1000 116 | 117 | .link https://research.swtch.com/interfaces Go Data Structures Interfaces (by @rsc) 118 | .link https://speakerdeck.com/campoy/understanding-the-interface Understanding the interface (by @campoy) 119 | 120 | * Channels 121 | 122 | .play code/chan.go 123 | 124 | * Channel internal structure 125 | 126 | .link https://github.com/golang/go/blob/master/src/runtime/chan.go chan.go 127 | 128 | .image image/chan-1.png 450 _ 129 | 130 | * Channel internal structure (2) 131 | - the receiving goroutines queue: a linked list without size limitation. Goroutines in this queue are called blocked receiving goroutines on this channel. 132 | - the sending goroutine queue: a linked list without size limitation. Goroutines in this queue are called blocked sending qgoroutines on this channel. 133 | - the value buffer queue. This is a circular queue. Its capacity is specified when createing the channel. 134 | + If it reaches the capacity, the channel is called in full status 135 | + If no values are stored in the value buffer queue, this channel is called in empty status 136 | + For a zero-capacity channel, it is always in both full and empty status 137 | 138 | A channel is referenced by all the goroutines in either the sending or receiving queue, so if neither of the two queues is empty, the channel will not be garbage collected. 139 | 140 | * Do things on channels 141 | - query the value buffer capacity of the channel `cap(ch)` 142 | - query the current number of values in the value buffer `len(ch)` 143 | - close the channel `close(ch)`. A non-nil channel can be closed for once. 144 | - send a value, `v` to the channel `ch`<-`v` 145 | - receive (and take out) a value from the channel `v,`ok`=`<-`ch` (`ok` is optional) 146 | 147 | All these operations are already synchronized, so no further synchronizations are needed to perform these operations. 148 | 149 | .link http://www.tapirgames.com/blog/golang-channel Channels in Golang 150 | .link http://www.tapirgames.com/blog/golang-concurrent-select-implementation Golang Concurrent select implementation 151 | 152 | * package runtime 153 | 154 | .image image/runtime.png 450 _ 155 | 156 | * runtime/HACKING.md 157 | 158 | .image image/runtime-hacking.png 600 _ 159 | 160 | * Maybe next? 161 | 162 | Inside Go core libraries 163 | 164 | - How `template/html` helps us avoid XSS? 165 | - Why `encoding/json` is not too fast, and how to improve it by 3x speed? 166 | - How `database/sql` handle connections pool, and how to write new `sql.Driver`? 167 | 168 | Go compiler tool chain 169 | 170 | - How to use `go/parser` to write Go tools like ` 171 | - How to user `go/types` to make type safe template engine and type safe orm? 172 | -------------------------------------------------------------------------------- /12/go-internals/image/chan-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/12/go-internals/image/chan-1.png -------------------------------------------------------------------------------- /12/go-internals/image/interfacetype.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/12/go-internals/image/interfacetype.png -------------------------------------------------------------------------------- /12/go-internals/image/itab.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/12/go-internals/image/itab.png -------------------------------------------------------------------------------- /12/go-internals/image/map-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/12/go-internals/image/map-2.png -------------------------------------------------------------------------------- /12/go-internals/image/map-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/12/go-internals/image/map-3.png -------------------------------------------------------------------------------- /12/go-internals/image/map.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/12/go-internals/image/map.png -------------------------------------------------------------------------------- /12/go-internals/image/runtime-hacking.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/12/go-internals/image/runtime-hacking.png -------------------------------------------------------------------------------- /12/go-internals/image/runtime.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/12/go-internals/image/runtime.png -------------------------------------------------------------------------------- /12/go-internals/image/slice-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/12/go-internals/image/slice-2.png -------------------------------------------------------------------------------- /12/go-internals/image/slice.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/12/go-internals/image/slice.png -------------------------------------------------------------------------------- /12/go-internals/image/sync_map-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/12/go-internals/image/sync_map-1.png -------------------------------------------------------------------------------- /12/go-internals/image/sync_map.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/12/go-internals/image/sync_map.png -------------------------------------------------------------------------------- /12/go-internals/image/sync_map_load.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/12/go-internals/image/sync_map_load.png -------------------------------------------------------------------------------- /12/go-internals/image/sync_map_store.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/12/go-internals/image/sync_map_store.png -------------------------------------------------------------------------------- /12/go-internals/image/type.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/12/go-internals/image/type.png -------------------------------------------------------------------------------- /13/go-db/README.md: -------------------------------------------------------------------------------- 1 | To execute code in slide, please install driver and set up database correctly. 2 | 3 | My code using mysql, root account with password 123, database tmp. 4 | -------------------------------------------------------------------------------- /13/go-db/code/advanceQuery.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "database/sql" 5 | "database/sql/driver" 6 | "encoding/json" 7 | "fmt" 8 | 9 | _ "github.com/go-sql-driver/mysql" 10 | ) 11 | 12 | // metadata definition 13 | type metadata struct { 14 | Job string 15 | Address string 16 | WalletID int64 17 | } 18 | 19 | func (c *metadata) Value() (val driver.Value, err error) { 20 | if c == nil { 21 | return 22 | } 23 | return json.Marshal(&c) 24 | } 25 | 26 | func (c *metadata) Scan(value interface{}) (err error) { 27 | if value == nil { 28 | return 29 | } else if v, ok := value.([]byte); ok { 30 | err = json.Unmarshal(v, c) 31 | return 32 | } 33 | return fmt.Errorf("Can not parse metadata") 34 | } // metadata end definition 35 | 36 | type person struct { 37 | Id int 38 | Name string 39 | National_id int64 40 | Metadata *metadata 41 | } 42 | 43 | func main() { 44 | db := connectAndClearData() 45 | 46 | // insert dummy person without metadata 47 | insertDummy(db) 48 | 49 | // insert jon snow with metadata 50 | if id, err := insertJonSnow(db); err != nil { 51 | panic(err) 52 | } else { 53 | fmt.Println("JonSnow has id:", id) 54 | } 55 | 56 | if persons, err := selectAllPeople(db); err != nil { 57 | panic(err) 58 | } else { 59 | for _, v := range persons { 60 | fmt.Printf("%v %+v\n", v, v.Metadata) 61 | } 62 | } 63 | } 64 | 65 | func insertJonSnow(db *sql.DB) (int64, error) { 66 | r, err := db.Exec("INSERT INTO person(name, national_id, metadata) VALUES (?,?,?)", 67 | "Jon Snow", 1, &metadata{ 68 | Job: "Actor", 69 | Address: "Vietnam", 70 | WalletID: 1234567, 71 | }) 72 | if err != nil { 73 | panic(err) 74 | } 75 | return r.LastInsertId() 76 | } 77 | 78 | func insertDummy(db *sql.DB) (int64, error) { 79 | r, err := db.Exec("INSERT INTO person(name, national_id) VALUES (?,?)", "Dummy", 2) 80 | if err != nil { 81 | panic(err) 82 | } 83 | return r.LastInsertId() 84 | } 85 | 86 | func selectAllPeople(db *sql.DB) (persons []*person, err error) { 87 | rows, err := db.Query("SELECT * FROM person") 88 | if err != nil { 89 | return nil, err 90 | } 91 | defer rows.Close() // very important 92 | 93 | persons = make([]*person, 0, 1000) 94 | for rows.Next() { 95 | var tmp person 96 | rows.Scan(&tmp.Id, &tmp.Name, &tmp.National_id, &tmp.Metadata) 97 | persons = append(persons, &tmp) 98 | } 99 | 100 | return 101 | } 102 | 103 | func connectAndClearData() *sql.DB { 104 | db, err := sql.Open("mysql", "root:123@tcp(localhost:3306)/tmp") 105 | if err != nil { 106 | panic(err) 107 | } 108 | 109 | if _, err := db.Exec("DELETE FROM person"); err != nil { 110 | panic(err) 111 | } 112 | 113 | return db 114 | } 115 | -------------------------------------------------------------------------------- /13/go-db/code/batchInsert.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "database/sql" 5 | "fmt" 6 | "strconv" 7 | 8 | _ "github.com/go-sql-driver/mysql" 9 | ) 10 | 11 | func main() { 12 | db, err := sql.Open("mysql", "root:123@tcp(localhost:3306)/tmp") 13 | if err != nil { 14 | panic(err) 15 | } 16 | 17 | db.Exec("DELETE FROM person") 18 | 19 | var tx *sql.Tx 20 | if tx, err = db.Begin(); err != nil { 21 | panic(err) 22 | } 23 | fmt.Println("Batch insert with error:", batchInsert(tx)) 24 | } 25 | 26 | func batchInsert(tx *sql.Tx) (err error) { 27 | shouldAutoRollBack := true 28 | defer func() { 29 | if err != nil && shouldAutoRollBack { 30 | tx.Rollback() 31 | } 32 | }() 33 | 34 | var stmt *sql.Stmt 35 | if stmt, err = tx.Prepare("INSERT INTO person(name, national_id) VALUES (?, ?)"); err != nil { 36 | return 37 | } 38 | for i := 0; i <= 100; i++ { 39 | if _, err = stmt.Exec(strconv.Itoa(i), i); err != nil { 40 | return 41 | } 42 | } 43 | 44 | if err = tx.Commit(); err != nil { 45 | shouldAutoRollBack = false 46 | } 47 | // done batch insert 48 | 49 | return 50 | } 51 | -------------------------------------------------------------------------------- /13/go-db/code/driverHook.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "database/sql" 5 | "fmt" 6 | 7 | _ "github.com/go-sql-driver/mysql" 8 | _ "github.com/lib/pq" 9 | ) 10 | 11 | // DDL 12 | const ( 13 | dropTable = `DROP TABLE IF EXISTS person` 14 | createTable = ` 15 | CREATE TABLE person ( 16 | id int(11) NOT NULL AUTO_INCREMENT, 17 | name varchar(20) DEFAULT NULL, 18 | national_id long NOT NULL DEFAULT 0, 19 | metadata longblob DEFAULT NULL, 20 | PRIMARY KEY (id) 21 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 22 | ` 23 | ) // END DDL 24 | 25 | func main() { 26 | // configure dsn 27 | dsn := "root:123@tcp(localhost:3306)/tmp" 28 | 29 | // open connection 30 | db, err := sql.Open("mysql", dsn) 31 | if err != nil { 32 | fmt.Println("Failed to create *DB object", err) 33 | } else { 34 | fmt.Println("Success to create *DB object") 35 | } 36 | 37 | // run script 38 | if err = script(db); err != nil { 39 | panic(err) 40 | } 41 | 42 | fmt.Println("Script ran well!") 43 | } 44 | 45 | func script(db *sql.DB) (err error) { 46 | if err = prepare(db); err != nil { 47 | return 48 | } 49 | 50 | return 51 | } 52 | 53 | func prepare(db *sql.DB) (err error) { 54 | if _, err = db.Exec(dropTable); err != nil { 55 | return 56 | } 57 | 58 | if _, err = db.Exec(createTable); err != nil { 59 | return 60 | } 61 | 62 | return 63 | } 64 | -------------------------------------------------------------------------------- /13/go-db/code/drivers/mysql/driver.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go-MySQL-Driver Authors. All rights reserved. 2 | // 3 | // This Source Code Form is subject to the terms of the Mozilla Public 4 | // License, v. 2.0. If a copy of the MPL was not distributed with this file, 5 | // You can obtain one at http://mozilla.org/MPL/2.0/. 6 | 7 | // Package mysql provides a MySQL driver for Go's database/sql package. 8 | // 9 | // The driver should be used via the database/sql package: 10 | // 11 | // import "database/sql" 12 | // import _ "github.com/go-sql-driver/mysql" 13 | // 14 | // db, err := sql.Open("mysql", "user:password@/dbname") 15 | // 16 | // See https://github.com/go-sql-driver/mysql#usage for details 17 | package mysql 18 | 19 | import ( 20 | "database/sql" 21 | "database/sql/driver" 22 | "net" 23 | ) 24 | 25 | // watcher interface is used for context support (From Go 1.8) 26 | type watcher interface { 27 | startWatcher() 28 | } 29 | 30 | // MySQLDriver is exported to make the driver directly accessible. 31 | // In general the driver is used via the database/sql package. 32 | type MySQLDriver struct{} 33 | 34 | // DialFunc is a function which can be used to establish the network connection. 35 | // Custom dial functions must be registered with RegisterDial 36 | type DialFunc func(addr string) (net.Conn, error) 37 | 38 | var dials map[string]DialFunc 39 | 40 | // RegisterDial registers a custom dial function. It can then be used by the 41 | // network address mynet(addr), where mynet is the registered new network. 42 | // addr is passed as a parameter to the dial function. 43 | func RegisterDial(net string, dial DialFunc) { 44 | if dials == nil { 45 | dials = make(map[string]DialFunc) 46 | } 47 | dials[net] = dial 48 | } 49 | 50 | // Open new Connection. 51 | // See https://github.com/go-sql-driver/mysql#dsn-data-source-name for how 52 | // the DSN string is formated 53 | func (d MySQLDriver) Open(dsn string) (driver.Conn, error) { 54 | var err error 55 | 56 | // New mysqlConn 57 | mc := &mysqlConn{ 58 | maxAllowedPacket: maxPacketSize, 59 | maxWriteSize: maxPacketSize - 1, 60 | closech: make(chan struct{}), 61 | } 62 | mc.cfg, err = ParseDSN(dsn) 63 | if err != nil { 64 | return nil, err 65 | } 66 | mc.parseTime = mc.cfg.ParseTime 67 | 68 | // Connect to Server 69 | if dial, ok := dials[mc.cfg.Net]; ok { 70 | mc.netConn, err = dial(mc.cfg.Addr) 71 | } else { 72 | nd := net.Dialer{Timeout: mc.cfg.Timeout} 73 | mc.netConn, err = nd.Dial(mc.cfg.Net, mc.cfg.Addr) 74 | } 75 | if err != nil { 76 | return nil, err 77 | } 78 | 79 | // Enable TCP Keepalives on TCP connections 80 | if tc, ok := mc.netConn.(*net.TCPConn); ok { 81 | if err := tc.SetKeepAlive(true); err != nil { 82 | // Don't send COM_QUIT before handshake. 83 | mc.netConn.Close() 84 | mc.netConn = nil 85 | return nil, err 86 | } 87 | } 88 | 89 | // Call startWatcher for context support (From Go 1.8) 90 | if s, ok := interface{}(mc).(watcher); ok { 91 | s.startWatcher() 92 | } 93 | 94 | mc.buf = newBuffer(mc.netConn) 95 | 96 | // Set I/O timeouts 97 | mc.buf.timeout = mc.cfg.ReadTimeout 98 | mc.writeTimeout = mc.cfg.WriteTimeout 99 | 100 | // Reading Handshake Initialization Packet 101 | cipher, err := mc.readInitPacket() 102 | if err != nil { 103 | mc.cleanup() 104 | return nil, err 105 | } 106 | 107 | // Send Client Authentication Packet 108 | if err = mc.writeAuthPacket(cipher); err != nil { 109 | mc.cleanup() 110 | return nil, err 111 | } 112 | 113 | // Handle response to auth packet, switch methods if possible 114 | if err = handleAuthResult(mc, cipher); err != nil { 115 | // Authentication failed and MySQL has already closed the connection 116 | // (https://dev.mysql.com/doc/internals/en/authentication-fails.html). 117 | // Do not send COM_QUIT, just cleanup and return the error. 118 | mc.cleanup() 119 | return nil, err 120 | } 121 | 122 | if mc.cfg.MaxAllowedPacket > 0 { 123 | mc.maxAllowedPacket = mc.cfg.MaxAllowedPacket 124 | } else { 125 | // Get max allowed packet size 126 | maxap, err := mc.getSystemVar("max_allowed_packet") 127 | if err != nil { 128 | mc.Close() 129 | return nil, err 130 | } 131 | mc.maxAllowedPacket = stringToInt(maxap) - 1 132 | } 133 | if mc.maxAllowedPacket < maxPacketSize { 134 | mc.maxWriteSize = mc.maxAllowedPacket 135 | } 136 | 137 | // Handle DSN Params 138 | err = mc.handleParams() 139 | if err != nil { 140 | mc.Close() 141 | return nil, err 142 | } 143 | 144 | return mc, nil 145 | } 146 | 147 | func handleAuthResult(mc *mysqlConn, oldCipher []byte) error { 148 | // Read Result Packet 149 | cipher, err := mc.readResultOK() 150 | if err == nil { 151 | return nil // auth successful 152 | } 153 | 154 | if mc.cfg == nil { 155 | return err // auth failed and retry not possible 156 | } 157 | 158 | // Retry auth if configured to do so. 159 | if mc.cfg.AllowOldPasswords && err == ErrOldPassword { 160 | // Retry with old authentication method. Note: there are edge cases 161 | // where this should work but doesn't; this is currently "wontfix": 162 | // https://github.com/go-sql-driver/mysql/issues/184 163 | 164 | // If CLIENT_PLUGIN_AUTH capability is not supported, no new cipher is 165 | // sent and we have to keep using the cipher sent in the init packet. 166 | if cipher == nil { 167 | cipher = oldCipher 168 | } 169 | 170 | if err = mc.writeOldAuthPacket(cipher); err != nil { 171 | return err 172 | } 173 | _, err = mc.readResultOK() 174 | } else if mc.cfg.AllowCleartextPasswords && err == ErrCleartextPassword { 175 | // Retry with clear text password for 176 | // http://dev.mysql.com/doc/refman/5.7/en/cleartext-authentication-plugin.html 177 | // http://dev.mysql.com/doc/refman/5.7/en/pam-authentication-plugin.html 178 | if err = mc.writeClearAuthPacket(); err != nil { 179 | return err 180 | } 181 | _, err = mc.readResultOK() 182 | } else if mc.cfg.AllowNativePasswords && err == ErrNativePassword { 183 | if err = mc.writeNativeAuthPacket(cipher); err != nil { 184 | return err 185 | } 186 | _, err = mc.readResultOK() 187 | } 188 | return err 189 | } 190 | 191 | func init() { 192 | sql.Register("mysql", &MySQLDriver{}) 193 | } 194 | -------------------------------------------------------------------------------- /13/go-db/code/lastInsertID.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "database/sql" 5 | "fmt" 6 | 7 | _ "github.com/go-sql-driver/mysql" 8 | ) 9 | 10 | func main() { 11 | db, err := sql.Open("mysql", "root:123@tcp(localhost:3306)/tmp") 12 | if err != nil { 13 | panic(err) 14 | } 15 | 16 | db.Exec("DELETE FROM person") 17 | 18 | var lastID int64 19 | if r, err := db.Exec("INSERT INTO person(name, national_id) VALUES (?,?), (?,?)", 20 | "A", "1", 21 | "B", "2"); err != nil { 22 | panic(err) 23 | } else { 24 | lastID, _ = r.LastInsertId() 25 | fmt.Println("Last insert id: ", lastID) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /13/go-db/code/normalQuery.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "database/sql" 6 | "fmt" 7 | 8 | _ "github.com/go-sql-driver/mysql" 9 | ) 10 | 11 | func main() { 12 | db, err := sql.Open("mysql", "root:123@tcp(localhost:3306)/tmp") 13 | if err != nil { 14 | panic(err) 15 | } 16 | 17 | var lastID int64 18 | if r, err := db.Exec("INSERT INTO person(name, national_id) VALUES (?,?)", "A", "1"); err != nil { 19 | panic(err) 20 | } else { 21 | lastID, _ = r.LastInsertId() 22 | fmt.Println("Last insert id: ", lastID) 23 | } 24 | 25 | if _, err := db.ExecContext(context.Background(), 26 | "DELETE FROM person WHERE id=@myID", 27 | sql.Named("myID", lastID)); err != nil { 28 | fmt.Println("You are right!", err) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /13/go-db/code/ping.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "database/sql" 5 | "fmt" 6 | "time" 7 | 8 | _ "github.com/go-sql-driver/mysql" 9 | ) 10 | 11 | func main() { 12 | db1, _ := sql.Open("mysql", "root:123@tcp(localhost:3306)/tmp") 13 | db1.SetMaxOpenConns(1) 14 | 15 | db2, _ := sql.Open("mysql", "root:123@tcp(localhost:3306)/tmp") 16 | db2.SetMaxOpenConns(1) 17 | 18 | for { 19 | if err := db1.Ping(); err != nil { 20 | fmt.Println("[Ping failed] ------ ", err) 21 | } 22 | 23 | if _, err := db2.Exec("SELECT 1"); err != nil { 24 | fmt.Println("[Select failed] ----- ", err) 25 | } 26 | 27 | fmt.Printf("\n\n") 28 | time.Sleep(10 * time.Second) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /13/go-db/images/cycleProcess.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/13/go-db/images/cycleProcess.png -------------------------------------------------------------------------------- /13/go-db/images/driverAndCore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/13/go-db/images/driverAndCore.png -------------------------------------------------------------------------------- /13/go-db/images/fun.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/13/go-db/images/fun.jpeg -------------------------------------------------------------------------------- /13/go-db/images/galera.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/13/go-db/images/galera.png -------------------------------------------------------------------------------- /13/go-db/images/galeraFail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/13/go-db/images/galeraFail.png -------------------------------------------------------------------------------- /13/go-db/images/getConnActivities.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/13/go-db/images/getConnActivities.png -------------------------------------------------------------------------------- /13/go-db/images/gomysql.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/13/go-db/images/gomysql.png -------------------------------------------------------------------------------- /13/go-db/images/initializeDBObj.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/13/go-db/images/initializeDBObj.png -------------------------------------------------------------------------------- /13/go-db/runslide.sh: -------------------------------------------------------------------------------- 1 | present -play -http localhost:9999 2 | -------------------------------------------------------------------------------- /13/go-synthesis/Sound synthesis w Golang.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/13/go-synthesis/Sound synthesis w Golang.pdf -------------------------------------------------------------------------------- /13/goa/beach.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/13/goa/beach.jpg -------------------------------------------------------------------------------- /13/goa/clean.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/13/goa/clean.jpg -------------------------------------------------------------------------------- /13/goa/deps_after.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/13/goa/deps_after.png -------------------------------------------------------------------------------- /13/goa/deps_before.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/13/goa/deps_before.png -------------------------------------------------------------------------------- /13/goa/doc.md: -------------------------------------------------------------------------------- 1 | ### Create only template 2 | 3 | POST api/template/passtype/{passTypeId} 4 | 5 | ```javascript 6 | POST /api/template/passtype/pass.eu.missmp.testing HTTP/1.1 7 | Host: localhost:8080 8 | Content-Type: application/json 9 | 10 | { 11 | "formatVersion": 1 12 | } 13 | ``` 14 | 15 | Response: 16 | 17 | ```javascript 18 | { 19 | "id": "31", 20 | "CreatedAt": "2017-08-29T06:09:01.1314307Z" 21 | } 22 | ``` 23 | -------------------------------------------------------------------------------- /13/goa/goa.slide: -------------------------------------------------------------------------------- 1 | Design First 2 | ReSTful APIs with goa 3 | 4 | Golang Vietnam Meetup 5 | 2 Jan 2018 6 | 7 | Dipl.-Ing. Vinh Hoi Le Chau 8 | Founder and CTO of Miss Moneypenny Technologies 9 | 10 | * Overview 11 | 12 | 1. Why API design first? 13 | 14 | 2. How goa works 15 | 16 | 3. Demo 17 | 18 | * Why API design first 19 | 20 | *Read*code* 21 | 22 | .code init.go 23 | 24 | .code init2.go 25 | 26 | * Why API design first 27 | 28 | *Focus*on*structure* 29 | 30 | before 31 | 32 | .image deps_before.png _ 1000 33 | 34 | after 35 | 36 | .image deps_after.png _ 1000 37 | 38 | * Why API design first 39 | 40 | *Docs*in*code* 41 | 42 | .code routes.go 43 | 44 | * Why API design first 45 | 46 | *Docs*in*markdown* 47 | 48 | .code doc.md 49 | 50 | * Why API design first 51 | 52 | *Driven*vs*Driven* 53 | 54 | - Backend often Domain/Model driven 55 | - Frontend often Prototype/Story driven 56 | - Timeline decoupling via API design 57 | 58 | 59 | * Why API design first 60 | 61 | *Driven*vs*Driven* 62 | 63 | CRUD, OO, MVC can lead to Naked Object pattern 64 | 65 | .image mvc.svg _ 300 66 | 67 | * Why API design first 68 | 69 | *Driven*vs*Driven* 70 | 71 | Focus on Use Case Layer 72 | 73 | .image clean.jpg _ 500 74 | 75 | * How goa works 76 | 77 | *Internal*DSL* 78 | 79 | .code subtemplates.go 80 | 81 | 82 | * How goa works 83 | 84 | *OpenAPI*Swagger* 85 | 86 | .code swagger.yaml 87 | 88 | * How goa works 89 | 90 | 1. Write design files in go (goa DSL) 91 | 2. Run goa (e.g. with go:generate) 92 | 3. Design is validated 93 | 4. Generates .go files for routing, security, controllers, validation, models, tests 94 | 5. Generates Swagger/OpenAPI files 95 | 6. Wire controller 96 | 7. Implement Handler 97 | 8. Use Swagger to document, mock, test, communicate 98 | 99 | * Demo 100 | 101 | : define 102 | : generate 103 | : implement 104 | : testing 105 | 106 | * Thank you! 107 | 108 | * We are hiring! 109 | 110 | Fresher/Junior/Senior Software Engineers 111 | 112 | .image beach.jpg _ 800 113 | 114 | * We are hiring! 115 | 116 | .image qr.jpg _ 500 117 | -------------------------------------------------------------------------------- /13/goa/init.go: -------------------------------------------------------------------------------- 1 | addressSvc := svc.AddressSvc{store.AddressStore{cruder, lister}} 2 | brandSvc := svc.BrandSvc{store.BrandStore{cruder, lister, beginer}} 3 | categorySvc := svc.CategorySvc{store.CategoryStore{cruder, lister, beginer}} 4 | companySvc := svc.CompanySvc{store.CompanyStore{cruder, lister, beginer}} 5 | feedbackSvc := svc.FeedbackSvc{store.FeedbackStore{cruder, lister}} 6 | imageSvc := svc.ImageSvc{store.ImageStore{conf, queryer}} 7 | invoiceSvc := svc.InvoiceSvc{store.InvoiceStore{cruder, queryer, beginer, lister}} 8 | contentSvc := svc.ContentSvc{store.ContentStore{cruder, lister, beginer}} 9 | -------------------------------------------------------------------------------- /13/goa/init2.go: -------------------------------------------------------------------------------- 1 | q := Q{ 2 | comctrl.AddressCtrl{addressSvc, userSvc, *shipmentSvc}, // HL 3 | comctrl.BrandCtrl{conf, brandSvc}, 4 | comctrl.CategoryCtrl{conf, categorySvc, *productSvc, tagSvc}, // HL 5 | ctrl.CompanyCtrl{companySvc}, 6 | comctrl.FeedbackCtrl{feedbackSvc}, 7 | ctrl.ImageCtrl{conf, imageSvc}, 8 | } 9 | -------------------------------------------------------------------------------- /13/goa/qr.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/13/goa/qr.jpg -------------------------------------------------------------------------------- /13/goa/routes.go: -------------------------------------------------------------------------------- 1 | /** 2 | * @api {get} /me/company/txs 3 | * @apiGroup shop me/business 4 | * @apiDescription list companies transactions 5 | * @apiPermission Business 6 | */ 7 | r.Path("/me/company/txs").Methods("POST").Handler(dc.With(txs.CompanyList)) // HL 8 | /** 9 | * @api {post} /me/orders/encrypted encrypted checkout 10 | * @apiGroup shop me/business 11 | * @apiDescription creates order from cart in request body, encrypting personal order info 12 | * @apiPermission Bank 13 | */ 14 | r.Path("/me/orders/encrypted").Methods("POST").Handler(dcBank.With(carts.EncryptedCheckout)) // HL 15 | /** 16 | * @api {post} /me/orders/onestep onestep checkout 17 | * @apiGroup shop me/business 18 | * @apiDescription creates order from cart in request body 19 | * @apiPermission Business 20 | */ 21 | r.Path("/me/orders/onestep").Methods("POST").Handler(dc.With(carts.BusinessOnestepCheckout)) // HL 22 | -------------------------------------------------------------------------------- /13/goa/subtemplates.go: -------------------------------------------------------------------------------- 1 | var _ = Resource("subtemplates", func() { 2 | DefaultMedia(SubtemplateMedia) 3 | BasePath("/api/subtemplate") 4 | 5 | Action("show", func() { 6 | Description("Get subtemplate") 7 | Routing(GET("/:subTemplateID")) 8 | Params(func() { 9 | Param("subTemplateID", Integer) 10 | }) 11 | Response(OK, SubtemplateMedia) 12 | Response(NotFound) 13 | Response(BadRequest, ErrorMedia) 14 | }) 15 | // ... 16 | }) 17 | -------------------------------------------------------------------------------- /13/goa/swagger.yaml: -------------------------------------------------------------------------------- 1 | swagger: "2.0" 2 | paths: 3 | /api/subtemplate/{subTemplateID}/fields: // HL 4 | get: 5 | - in: path 6 | name: subTemplateID 7 | required: true 8 | type: integer 9 | produces: 10 | - application/vnd.localizedpassfieldmedia+json 11 | responses: 12 | "200": 13 | description: OK 14 | security: 15 | - JWT: 16 | - api:access 17 | -------------------------------------------------------------------------------- /14/grpc/README.md: -------------------------------------------------------------------------------- 1 | ## Notes 2 | 3 | * I used gogo protobuf for protoc gen. 4 | * Various benchmark in folder bench. 5 | * Please run `sh runslide.sh` and open slide at `http://localhost:10000` -------------------------------------------------------------------------------- /14/grpc/bench/multi/grpcWithETCD/client/app.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "strings" 7 | "sync" 8 | "sync/atomic" 9 | "time" 10 | 11 | etcdClient "github.com/coreos/etcd/clientv3" 12 | etcdnaming "github.com/coreos/etcd/clientv3/naming" 13 | grpc "google.golang.org/grpc" 14 | ) 15 | 16 | const ( 17 | serviceName = "helloService" 18 | ) 19 | 20 | var numWorker = 50 21 | var numRequest = 1000000 22 | var hClient HelloClient 23 | var successCounter uint64 24 | 25 | var p = &Payload{ 26 | A: "12345678901234567890", 27 | B: "abcdefghijklmnopqus", 28 | C: 43545, 29 | D: "asgkasjeglkajsgjalsjdglaskdjglads", 30 | E: true, 31 | F: -135465748, 32 | G: "gejoiwbbbdfasaaaaaaaaaaaaaaaaa", 33 | } 34 | 35 | func main() { 36 | ch := make(chan struct{}, numWorker) 37 | 38 | // worker 39 | var wg sync.WaitGroup 40 | for i := 0; i < numWorker; i++ { 41 | wg.Add(1) 42 | go func() { 43 | for range ch { 44 | doTask() 45 | } 46 | wg.Done() 47 | }() 48 | } 49 | 50 | // get etcd client 51 | cli, _ := getETCDClient() 52 | 53 | // init balancer 54 | balancer := grpc.RoundRobin(&etcdnaming.GRPCResolver{Client: cli}) 55 | conn, err := grpc.Dial(serviceName, grpc.WithInsecure(), grpc.WithBalancer(balancer)) 56 | if err != nil { 57 | return 58 | } 59 | hClient = NewHelloClient(conn) 60 | 61 | time.Sleep(2 * time.Second) 62 | 63 | start := time.Now() 64 | for i := 0; i < numRequest; i++ { 65 | ch <- struct{}{} 66 | } 67 | close(ch) 68 | wg.Wait() 69 | end := time.Now() 70 | 71 | fmt.Println(end.Sub(start).Seconds(), fmt.Sprintf("%d / %d", successCounter, numRequest)) 72 | } 73 | 74 | func doTask() { 75 | _, err := hClient.SayHi(context.Background(), p) 76 | if err != nil { 77 | return 78 | } 79 | 80 | atomic.AddUint64(&successCounter, 1) 81 | } 82 | 83 | func getETCDClient() (*etcdClient.Client, error) { 84 | return etcdClient.New(etcdClient.Config{ 85 | Endpoints: strings.Split("http://127.0.0.1:2379", ","), // etcd endpoints 86 | }) 87 | } 88 | -------------------------------------------------------------------------------- /14/grpc/bench/multi/grpcWithETCD/client/common.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-gogo. DO NOT EDIT. 2 | // source: common.proto 3 | 4 | /* 5 | Package main is a generated protocol buffer package. 6 | 7 | It is generated from these files: 8 | common.proto 9 | 10 | It has these top-level messages: 11 | Payload 12 | */ 13 | package main 14 | 15 | import proto "github.com/gogo/protobuf/proto" 16 | import fmt "fmt" 17 | import math "math" 18 | 19 | import context "golang.org/x/net/context" 20 | import grpc "google.golang.org/grpc" 21 | 22 | // Reference imports to suppress errors if they are not otherwise used. 23 | var _ = proto.Marshal 24 | var _ = fmt.Errorf 25 | var _ = math.Inf 26 | 27 | // This is a compile-time assertion to ensure that this generated file 28 | // is compatible with the proto package it is being compiled against. 29 | // A compilation error at this line likely means your copy of the 30 | // proto package needs to be updated. 31 | const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package 32 | 33 | type Payload struct { 34 | A string `protobuf:"bytes,1,opt,name=A,proto3" json:"A,omitempty"` 35 | B string `protobuf:"bytes,2,opt,name=B,proto3" json:"B,omitempty"` 36 | C int32 `protobuf:"varint,3,opt,name=C,proto3" json:"C,omitempty"` 37 | D string `protobuf:"bytes,4,opt,name=D,proto3" json:"D,omitempty"` 38 | E bool `protobuf:"varint,5,opt,name=E,proto3" json:"E,omitempty"` 39 | F int64 `protobuf:"varint,6,opt,name=F,proto3" json:"F,omitempty"` 40 | G string `protobuf:"bytes,7,opt,name=G,proto3" json:"G,omitempty"` 41 | } 42 | 43 | func (m *Payload) Reset() { *m = Payload{} } 44 | func (m *Payload) String() string { return proto.CompactTextString(m) } 45 | func (*Payload) ProtoMessage() {} 46 | func (*Payload) Descriptor() ([]byte, []int) { return fileDescriptorCommon, []int{0} } 47 | 48 | func (m *Payload) GetA() string { 49 | if m != nil { 50 | return m.A 51 | } 52 | return "" 53 | } 54 | 55 | func (m *Payload) GetB() string { 56 | if m != nil { 57 | return m.B 58 | } 59 | return "" 60 | } 61 | 62 | func (m *Payload) GetC() int32 { 63 | if m != nil { 64 | return m.C 65 | } 66 | return 0 67 | } 68 | 69 | func (m *Payload) GetD() string { 70 | if m != nil { 71 | return m.D 72 | } 73 | return "" 74 | } 75 | 76 | func (m *Payload) GetE() bool { 77 | if m != nil { 78 | return m.E 79 | } 80 | return false 81 | } 82 | 83 | func (m *Payload) GetF() int64 { 84 | if m != nil { 85 | return m.F 86 | } 87 | return 0 88 | } 89 | 90 | func (m *Payload) GetG() string { 91 | if m != nil { 92 | return m.G 93 | } 94 | return "" 95 | } 96 | 97 | func init() { 98 | proto.RegisterType((*Payload)(nil), "main.Payload") 99 | } 100 | 101 | // Reference imports to suppress errors if they are not otherwise used. 102 | var _ context.Context 103 | var _ grpc.ClientConn 104 | 105 | // This is a compile-time assertion to ensure that this generated file 106 | // is compatible with the grpc package it is being compiled against. 107 | const _ = grpc.SupportPackageIsVersion4 108 | 109 | // Client API for Hello service 110 | 111 | type HelloClient interface { 112 | SayHi(ctx context.Context, in *Payload, opts ...grpc.CallOption) (*Payload, error) 113 | } 114 | 115 | type helloClient struct { 116 | cc *grpc.ClientConn 117 | } 118 | 119 | func NewHelloClient(cc *grpc.ClientConn) HelloClient { 120 | return &helloClient{cc} 121 | } 122 | 123 | func (c *helloClient) SayHi(ctx context.Context, in *Payload, opts ...grpc.CallOption) (*Payload, error) { 124 | out := new(Payload) 125 | err := grpc.Invoke(ctx, "/main.Hello/SayHi", in, out, c.cc, opts...) 126 | if err != nil { 127 | return nil, err 128 | } 129 | return out, nil 130 | } 131 | 132 | // Server API for Hello service 133 | 134 | type HelloServer interface { 135 | SayHi(context.Context, *Payload) (*Payload, error) 136 | } 137 | 138 | func RegisterHelloServer(s *grpc.Server, srv HelloServer) { 139 | s.RegisterService(&_Hello_serviceDesc, srv) 140 | } 141 | 142 | func _Hello_SayHi_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 143 | in := new(Payload) 144 | if err := dec(in); err != nil { 145 | return nil, err 146 | } 147 | if interceptor == nil { 148 | return srv.(HelloServer).SayHi(ctx, in) 149 | } 150 | info := &grpc.UnaryServerInfo{ 151 | Server: srv, 152 | FullMethod: "/main.Hello/SayHi", 153 | } 154 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 155 | return srv.(HelloServer).SayHi(ctx, req.(*Payload)) 156 | } 157 | return interceptor(ctx, in, info, handler) 158 | } 159 | 160 | var _Hello_serviceDesc = grpc.ServiceDesc{ 161 | ServiceName: "main.Hello", 162 | HandlerType: (*HelloServer)(nil), 163 | Methods: []grpc.MethodDesc{ 164 | { 165 | MethodName: "SayHi", 166 | Handler: _Hello_SayHi_Handler, 167 | }, 168 | }, 169 | Streams: []grpc.StreamDesc{}, 170 | Metadata: "common.proto", 171 | } 172 | 173 | func init() { proto.RegisterFile("common.proto", fileDescriptorCommon) } 174 | 175 | var fileDescriptorCommon = []byte{ 176 | // 162 bytes of a gzipped FileDescriptorProto 177 | 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x49, 0xce, 0xcf, 0xcd, 178 | 0xcd, 0xcf, 0xd3, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0xc9, 0x4d, 0xcc, 0xcc, 0x53, 0xca, 179 | 0xe6, 0x62, 0x0f, 0x48, 0xac, 0xcc, 0xc9, 0x4f, 0x4c, 0x11, 0xe2, 0xe1, 0x62, 0x74, 0x94, 0x60, 180 | 0x54, 0x60, 0xd4, 0xe0, 0x0c, 0x62, 0x74, 0x04, 0xf1, 0x9c, 0x24, 0x98, 0x20, 0x3c, 0x27, 0x10, 181 | 0xcf, 0x59, 0x82, 0x59, 0x81, 0x51, 0x83, 0x35, 0x88, 0xd1, 0x19, 0xc4, 0x73, 0x91, 0x60, 0x81, 182 | 0xc8, 0xb9, 0x80, 0x78, 0xae, 0x12, 0xac, 0x0a, 0x8c, 0x1a, 0x1c, 0x41, 0x8c, 0xae, 0x20, 0x9e, 183 | 0x9b, 0x04, 0x9b, 0x02, 0xa3, 0x06, 0x73, 0x10, 0xa3, 0x1b, 0x88, 0xe7, 0x2e, 0xc1, 0x0e, 0x51, 184 | 0xe9, 0x6e, 0xa4, 0xc7, 0xc5, 0xea, 0x91, 0x9a, 0x93, 0x93, 0x2f, 0xa4, 0xca, 0xc5, 0x1a, 0x9c, 185 | 0x58, 0xe9, 0x91, 0x29, 0xc4, 0xab, 0x07, 0x72, 0x85, 0x1e, 0xd4, 0x09, 0x52, 0xa8, 0xdc, 0x24, 186 | 0x36, 0xb0, 0x4b, 0x8d, 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0x8a, 0xda, 0x25, 0x2c, 0xb9, 0x00, 187 | 0x00, 0x00, 188 | } 189 | -------------------------------------------------------------------------------- /14/grpc/bench/multi/grpcWithETCD/client/vendor.conf: -------------------------------------------------------------------------------- 1 | # package 2 | github.com/linxGnu/meetup/14/grpc/bench/multi/grpc/client 3 | 4 | # import 5 | github.com/coreos/etcd v3.3.0-rc.0-1213-g62dfb89a8 6 | github.com/coreos/go-systemd v16-42-gd1b7d05 7 | github.com/coreos/pkg v3-13-g97fdf19 8 | github.com/gogo/protobuf v1.0.0-14-g1ef32a8b 9 | github.com/golang/protobuf v1.1.0 10 | go.uber.org/atomic v1.3.2 11 | go.uber.org/multierr v1.1.0-2-gddea229 12 | go.uber.org/zap v1.8.0-2-g2dc8d10 13 | golang.org/x/net 640f462 14 | golang.org/x/text v0.3.0-47-g7922cc4 15 | google.golang.org/genproto 86e600f 16 | google.golang.org/grpc v1.8.1-161-ge944391 17 | -------------------------------------------------------------------------------- /14/grpc/bench/multi/grpcWithETCD/protos/common.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-gogo. DO NOT EDIT. 2 | // source: common.proto 3 | 4 | /* 5 | Package main is a generated protocol buffer package. 6 | 7 | It is generated from these files: 8 | common.proto 9 | 10 | It has these top-level messages: 11 | Payload 12 | */ 13 | package main 14 | 15 | import proto "github.com/gogo/protobuf/proto" 16 | import fmt "fmt" 17 | import math "math" 18 | 19 | import context "golang.org/x/net/context" 20 | import grpc "google.golang.org/grpc" 21 | 22 | // Reference imports to suppress errors if they are not otherwise used. 23 | var _ = proto.Marshal 24 | var _ = fmt.Errorf 25 | var _ = math.Inf 26 | 27 | // This is a compile-time assertion to ensure that this generated file 28 | // is compatible with the proto package it is being compiled against. 29 | // A compilation error at this line likely means your copy of the 30 | // proto package needs to be updated. 31 | const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package 32 | 33 | type Payload struct { 34 | A string `protobuf:"bytes,1,opt,name=A,proto3" json:"A,omitempty"` 35 | B string `protobuf:"bytes,2,opt,name=B,proto3" json:"B,omitempty"` 36 | C int32 `protobuf:"varint,3,opt,name=C,proto3" json:"C,omitempty"` 37 | D string `protobuf:"bytes,4,opt,name=D,proto3" json:"D,omitempty"` 38 | E bool `protobuf:"varint,5,opt,name=E,proto3" json:"E,omitempty"` 39 | F int64 `protobuf:"varint,6,opt,name=F,proto3" json:"F,omitempty"` 40 | G string `protobuf:"bytes,7,opt,name=G,proto3" json:"G,omitempty"` 41 | } 42 | 43 | func (m *Payload) Reset() { *m = Payload{} } 44 | func (m *Payload) String() string { return proto.CompactTextString(m) } 45 | func (*Payload) ProtoMessage() {} 46 | func (*Payload) Descriptor() ([]byte, []int) { return fileDescriptorCommon, []int{0} } 47 | 48 | func (m *Payload) GetA() string { 49 | if m != nil { 50 | return m.A 51 | } 52 | return "" 53 | } 54 | 55 | func (m *Payload) GetB() string { 56 | if m != nil { 57 | return m.B 58 | } 59 | return "" 60 | } 61 | 62 | func (m *Payload) GetC() int32 { 63 | if m != nil { 64 | return m.C 65 | } 66 | return 0 67 | } 68 | 69 | func (m *Payload) GetD() string { 70 | if m != nil { 71 | return m.D 72 | } 73 | return "" 74 | } 75 | 76 | func (m *Payload) GetE() bool { 77 | if m != nil { 78 | return m.E 79 | } 80 | return false 81 | } 82 | 83 | func (m *Payload) GetF() int64 { 84 | if m != nil { 85 | return m.F 86 | } 87 | return 0 88 | } 89 | 90 | func (m *Payload) GetG() string { 91 | if m != nil { 92 | return m.G 93 | } 94 | return "" 95 | } 96 | 97 | func init() { 98 | proto.RegisterType((*Payload)(nil), "main.Payload") 99 | } 100 | 101 | // Reference imports to suppress errors if they are not otherwise used. 102 | var _ context.Context 103 | var _ grpc.ClientConn 104 | 105 | // This is a compile-time assertion to ensure that this generated file 106 | // is compatible with the grpc package it is being compiled against. 107 | const _ = grpc.SupportPackageIsVersion4 108 | 109 | // Client API for Hello service 110 | 111 | type HelloClient interface { 112 | SayHi(ctx context.Context, in *Payload, opts ...grpc.CallOption) (*Payload, error) 113 | } 114 | 115 | type helloClient struct { 116 | cc *grpc.ClientConn 117 | } 118 | 119 | func NewHelloClient(cc *grpc.ClientConn) HelloClient { 120 | return &helloClient{cc} 121 | } 122 | 123 | func (c *helloClient) SayHi(ctx context.Context, in *Payload, opts ...grpc.CallOption) (*Payload, error) { 124 | out := new(Payload) 125 | err := grpc.Invoke(ctx, "/main.Hello/SayHi", in, out, c.cc, opts...) 126 | if err != nil { 127 | return nil, err 128 | } 129 | return out, nil 130 | } 131 | 132 | // Server API for Hello service 133 | 134 | type HelloServer interface { 135 | SayHi(context.Context, *Payload) (*Payload, error) 136 | } 137 | 138 | func RegisterHelloServer(s *grpc.Server, srv HelloServer) { 139 | s.RegisterService(&_Hello_serviceDesc, srv) 140 | } 141 | 142 | func _Hello_SayHi_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 143 | in := new(Payload) 144 | if err := dec(in); err != nil { 145 | return nil, err 146 | } 147 | if interceptor == nil { 148 | return srv.(HelloServer).SayHi(ctx, in) 149 | } 150 | info := &grpc.UnaryServerInfo{ 151 | Server: srv, 152 | FullMethod: "/main.Hello/SayHi", 153 | } 154 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 155 | return srv.(HelloServer).SayHi(ctx, req.(*Payload)) 156 | } 157 | return interceptor(ctx, in, info, handler) 158 | } 159 | 160 | var _Hello_serviceDesc = grpc.ServiceDesc{ 161 | ServiceName: "main.Hello", 162 | HandlerType: (*HelloServer)(nil), 163 | Methods: []grpc.MethodDesc{ 164 | { 165 | MethodName: "SayHi", 166 | Handler: _Hello_SayHi_Handler, 167 | }, 168 | }, 169 | Streams: []grpc.StreamDesc{}, 170 | Metadata: "common.proto", 171 | } 172 | 173 | func init() { proto.RegisterFile("common.proto", fileDescriptorCommon) } 174 | 175 | var fileDescriptorCommon = []byte{ 176 | // 162 bytes of a gzipped FileDescriptorProto 177 | 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x49, 0xce, 0xcf, 0xcd, 178 | 0xcd, 0xcf, 0xd3, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0xc9, 0x4d, 0xcc, 0xcc, 0x53, 0xca, 179 | 0xe6, 0x62, 0x0f, 0x48, 0xac, 0xcc, 0xc9, 0x4f, 0x4c, 0x11, 0xe2, 0xe1, 0x62, 0x74, 0x94, 0x60, 180 | 0x54, 0x60, 0xd4, 0xe0, 0x0c, 0x62, 0x74, 0x04, 0xf1, 0x9c, 0x24, 0x98, 0x20, 0x3c, 0x27, 0x10, 181 | 0xcf, 0x59, 0x82, 0x59, 0x81, 0x51, 0x83, 0x35, 0x88, 0xd1, 0x19, 0xc4, 0x73, 0x91, 0x60, 0x81, 182 | 0xc8, 0xb9, 0x80, 0x78, 0xae, 0x12, 0xac, 0x0a, 0x8c, 0x1a, 0x1c, 0x41, 0x8c, 0xae, 0x20, 0x9e, 183 | 0x9b, 0x04, 0x9b, 0x02, 0xa3, 0x06, 0x73, 0x10, 0xa3, 0x1b, 0x88, 0xe7, 0x2e, 0xc1, 0x0e, 0x51, 184 | 0xe9, 0x6e, 0xa4, 0xc7, 0xc5, 0xea, 0x91, 0x9a, 0x93, 0x93, 0x2f, 0xa4, 0xca, 0xc5, 0x1a, 0x9c, 185 | 0x58, 0xe9, 0x91, 0x29, 0xc4, 0xab, 0x07, 0x72, 0x85, 0x1e, 0xd4, 0x09, 0x52, 0xa8, 0xdc, 0x24, 186 | 0x36, 0xb0, 0x4b, 0x8d, 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0x8a, 0xda, 0x25, 0x2c, 0xb9, 0x00, 187 | 0x00, 0x00, 188 | } 189 | -------------------------------------------------------------------------------- /14/grpc/bench/multi/grpcWithETCD/protos/common.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package main; 4 | 5 | service Hello { 6 | rpc SayHi(Payload) returns (Payload); 7 | } 8 | 9 | message Payload { 10 | string A = 1; 11 | string B = 2; 12 | int32 C = 3; 13 | string D = 4; 14 | bool E = 5; 15 | int64 F = 6; 16 | string G = 7; 17 | } -------------------------------------------------------------------------------- /14/grpc/bench/multi/grpcWithETCD/protos/gen.sh: -------------------------------------------------------------------------------- 1 | 2 | #!/bin/bash 3 | my_dir=`dirname $0` 4 | 5 | protoc -I=$my_dir -I=$GOPATH/src -I=$GOPATH/src/github.com/gogo/protobuf/protobuf --gogo_out=plugins=grpc:$my_dir/ $my_dir/*.proto -------------------------------------------------------------------------------- /14/grpc/bench/multi/grpcWithETCD/server1/app.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "net" 7 | "os" 8 | "os/signal" 9 | "strings" 10 | "sync" 11 | "syscall" 12 | "time" 13 | 14 | etcdClient "github.com/coreos/etcd/clientv3" 15 | etcdnaming "github.com/coreos/etcd/clientv3/naming" 16 | grpc "google.golang.org/grpc" 17 | naming "google.golang.org/grpc/naming" 18 | ) 19 | 20 | const ( 21 | publicIP = "127.0.0.1" 22 | publicPort = 9903 23 | serviceName = "helloService" 24 | ) 25 | 26 | func main() { 27 | // os signal handling 28 | sigs := make(chan os.Signal, 10) 29 | signal.Notify(sigs, syscall.SIGINT, syscall.SIGQUIT, syscall.SIGKILL, syscall.SIGTERM, syscall.SIGSTOP, syscall.SIGTSTP, syscall.SIGEMT) 30 | 31 | // get etcd client 32 | cli, _ := getETCDClient() 33 | 34 | // try to listening to bind address 35 | listen, err := net.Listen("tcp", fmt.Sprintf(":%d", publicPort)) 36 | if err != nil { 37 | return 38 | } 39 | s := grpc.NewServer() 40 | RegisterHelloServer(s, &helloServer{}) 41 | 42 | go func() { 43 | if e := s.Serve(listen); e != nil { 44 | panic(e) 45 | } 46 | }() 47 | 48 | // keep alive with etcd 49 | kch, wg := make(chan struct{}, 1), sync.WaitGroup{} 50 | wg.Add(1) 51 | go func() { 52 | defer wg.Done() 53 | 54 | for { 55 | select { 56 | case <-kch: 57 | return 58 | default: 59 | time.Sleep(10 * time.Millisecond) 60 | } 61 | 62 | ctx, cancel := context.WithTimeout(context.Background(), 50*time.Millisecond) 63 | lease, er := cli.Grant(ctx, 1) 64 | if er != nil || lease == nil { 65 | cancel() 66 | fmt.Println(er) 67 | continue 68 | } 69 | <-ctx.Done() 70 | cancel() 71 | 72 | // attach key with lease 73 | ctx, cancel = context.WithTimeout(context.Background(), 50*time.Millisecond) 74 | resolver := &etcdnaming.GRPCResolver{Client: cli} 75 | if er = resolver.Update(ctx, serviceName, naming.Update{ 76 | Op: naming.Add, 77 | Addr: fmt.Sprintf("%s:%d", publicIP, publicPort), 78 | }, etcdClient.WithLease(lease.ID)); er != nil { 79 | cancel() 80 | fmt.Println(er) 81 | continue 82 | } 83 | <-ctx.Done() 84 | cancel() 85 | 86 | // keep a live lease 87 | keepAliveCh, er := cli.KeepAlive(context.Background(), lease.ID) 88 | if er != nil { 89 | fmt.Println(er) 90 | continue 91 | } 92 | 93 | L: 94 | for { 95 | select { 96 | case rp, opened := <-keepAliveCh: 97 | // The returned "LeaseKeepAliveResponse" channel closes if underlying keep 98 | // alive stream is interrupted in some way the client cannot handle itself; 99 | // given context "ctx" is canceled or timed out. "LeaseKeepAliveResponse" 100 | // from this closed channel is nil. 101 | if rp == nil || !opened { 102 | break L 103 | } 104 | case <-kch: 105 | return 106 | } 107 | } 108 | } 109 | }() 110 | 111 | <-sigs 112 | 113 | // notify we need to stop 114 | kch <- struct{}{} 115 | 116 | // Stop server now 117 | s.Stop() 118 | } 119 | 120 | func getETCDClient() (*etcdClient.Client, error) { 121 | return etcdClient.New(etcdClient.Config{ 122 | Endpoints: strings.Split("http://127.0.0.1:2379", ","), // etcd endpoints 123 | }) 124 | } 125 | 126 | type helloServer struct{} 127 | 128 | func (c *helloServer) SayHi(ctx context.Context, req *Payload) (resp *Payload, err error) { 129 | return req, nil 130 | } 131 | -------------------------------------------------------------------------------- /14/grpc/bench/multi/grpcWithETCD/server1/common.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-gogo. DO NOT EDIT. 2 | // source: common.proto 3 | 4 | /* 5 | Package main is a generated protocol buffer package. 6 | 7 | It is generated from these files: 8 | common.proto 9 | 10 | It has these top-level messages: 11 | Payload 12 | */ 13 | package main 14 | 15 | import proto "github.com/gogo/protobuf/proto" 16 | import fmt "fmt" 17 | import math "math" 18 | 19 | import context "golang.org/x/net/context" 20 | import grpc "google.golang.org/grpc" 21 | 22 | // Reference imports to suppress errors if they are not otherwise used. 23 | var _ = proto.Marshal 24 | var _ = fmt.Errorf 25 | var _ = math.Inf 26 | 27 | // This is a compile-time assertion to ensure that this generated file 28 | // is compatible with the proto package it is being compiled against. 29 | // A compilation error at this line likely means your copy of the 30 | // proto package needs to be updated. 31 | const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package 32 | 33 | type Payload struct { 34 | A string `protobuf:"bytes,1,opt,name=A,proto3" json:"A,omitempty"` 35 | B string `protobuf:"bytes,2,opt,name=B,proto3" json:"B,omitempty"` 36 | C int32 `protobuf:"varint,3,opt,name=C,proto3" json:"C,omitempty"` 37 | D string `protobuf:"bytes,4,opt,name=D,proto3" json:"D,omitempty"` 38 | E bool `protobuf:"varint,5,opt,name=E,proto3" json:"E,omitempty"` 39 | F int64 `protobuf:"varint,6,opt,name=F,proto3" json:"F,omitempty"` 40 | G string `protobuf:"bytes,7,opt,name=G,proto3" json:"G,omitempty"` 41 | } 42 | 43 | func (m *Payload) Reset() { *m = Payload{} } 44 | func (m *Payload) String() string { return proto.CompactTextString(m) } 45 | func (*Payload) ProtoMessage() {} 46 | func (*Payload) Descriptor() ([]byte, []int) { return fileDescriptorCommon, []int{0} } 47 | 48 | func (m *Payload) GetA() string { 49 | if m != nil { 50 | return m.A 51 | } 52 | return "" 53 | } 54 | 55 | func (m *Payload) GetB() string { 56 | if m != nil { 57 | return m.B 58 | } 59 | return "" 60 | } 61 | 62 | func (m *Payload) GetC() int32 { 63 | if m != nil { 64 | return m.C 65 | } 66 | return 0 67 | } 68 | 69 | func (m *Payload) GetD() string { 70 | if m != nil { 71 | return m.D 72 | } 73 | return "" 74 | } 75 | 76 | func (m *Payload) GetE() bool { 77 | if m != nil { 78 | return m.E 79 | } 80 | return false 81 | } 82 | 83 | func (m *Payload) GetF() int64 { 84 | if m != nil { 85 | return m.F 86 | } 87 | return 0 88 | } 89 | 90 | func (m *Payload) GetG() string { 91 | if m != nil { 92 | return m.G 93 | } 94 | return "" 95 | } 96 | 97 | func init() { 98 | proto.RegisterType((*Payload)(nil), "main.Payload") 99 | } 100 | 101 | // Reference imports to suppress errors if they are not otherwise used. 102 | var _ context.Context 103 | var _ grpc.ClientConn 104 | 105 | // This is a compile-time assertion to ensure that this generated file 106 | // is compatible with the grpc package it is being compiled against. 107 | const _ = grpc.SupportPackageIsVersion4 108 | 109 | // Client API for Hello service 110 | 111 | type HelloClient interface { 112 | SayHi(ctx context.Context, in *Payload, opts ...grpc.CallOption) (*Payload, error) 113 | } 114 | 115 | type helloClient struct { 116 | cc *grpc.ClientConn 117 | } 118 | 119 | func NewHelloClient(cc *grpc.ClientConn) HelloClient { 120 | return &helloClient{cc} 121 | } 122 | 123 | func (c *helloClient) SayHi(ctx context.Context, in *Payload, opts ...grpc.CallOption) (*Payload, error) { 124 | out := new(Payload) 125 | err := grpc.Invoke(ctx, "/main.Hello/SayHi", in, out, c.cc, opts...) 126 | if err != nil { 127 | return nil, err 128 | } 129 | return out, nil 130 | } 131 | 132 | // Server API for Hello service 133 | 134 | type HelloServer interface { 135 | SayHi(context.Context, *Payload) (*Payload, error) 136 | } 137 | 138 | func RegisterHelloServer(s *grpc.Server, srv HelloServer) { 139 | s.RegisterService(&_Hello_serviceDesc, srv) 140 | } 141 | 142 | func _Hello_SayHi_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 143 | in := new(Payload) 144 | if err := dec(in); err != nil { 145 | return nil, err 146 | } 147 | if interceptor == nil { 148 | return srv.(HelloServer).SayHi(ctx, in) 149 | } 150 | info := &grpc.UnaryServerInfo{ 151 | Server: srv, 152 | FullMethod: "/main.Hello/SayHi", 153 | } 154 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 155 | return srv.(HelloServer).SayHi(ctx, req.(*Payload)) 156 | } 157 | return interceptor(ctx, in, info, handler) 158 | } 159 | 160 | var _Hello_serviceDesc = grpc.ServiceDesc{ 161 | ServiceName: "main.Hello", 162 | HandlerType: (*HelloServer)(nil), 163 | Methods: []grpc.MethodDesc{ 164 | { 165 | MethodName: "SayHi", 166 | Handler: _Hello_SayHi_Handler, 167 | }, 168 | }, 169 | Streams: []grpc.StreamDesc{}, 170 | Metadata: "common.proto", 171 | } 172 | 173 | func init() { proto.RegisterFile("common.proto", fileDescriptorCommon) } 174 | 175 | var fileDescriptorCommon = []byte{ 176 | // 162 bytes of a gzipped FileDescriptorProto 177 | 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x49, 0xce, 0xcf, 0xcd, 178 | 0xcd, 0xcf, 0xd3, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0xc9, 0x4d, 0xcc, 0xcc, 0x53, 0xca, 179 | 0xe6, 0x62, 0x0f, 0x48, 0xac, 0xcc, 0xc9, 0x4f, 0x4c, 0x11, 0xe2, 0xe1, 0x62, 0x74, 0x94, 0x60, 180 | 0x54, 0x60, 0xd4, 0xe0, 0x0c, 0x62, 0x74, 0x04, 0xf1, 0x9c, 0x24, 0x98, 0x20, 0x3c, 0x27, 0x10, 181 | 0xcf, 0x59, 0x82, 0x59, 0x81, 0x51, 0x83, 0x35, 0x88, 0xd1, 0x19, 0xc4, 0x73, 0x91, 0x60, 0x81, 182 | 0xc8, 0xb9, 0x80, 0x78, 0xae, 0x12, 0xac, 0x0a, 0x8c, 0x1a, 0x1c, 0x41, 0x8c, 0xae, 0x20, 0x9e, 183 | 0x9b, 0x04, 0x9b, 0x02, 0xa3, 0x06, 0x73, 0x10, 0xa3, 0x1b, 0x88, 0xe7, 0x2e, 0xc1, 0x0e, 0x51, 184 | 0xe9, 0x6e, 0xa4, 0xc7, 0xc5, 0xea, 0x91, 0x9a, 0x93, 0x93, 0x2f, 0xa4, 0xca, 0xc5, 0x1a, 0x9c, 185 | 0x58, 0xe9, 0x91, 0x29, 0xc4, 0xab, 0x07, 0x72, 0x85, 0x1e, 0xd4, 0x09, 0x52, 0xa8, 0xdc, 0x24, 186 | 0x36, 0xb0, 0x4b, 0x8d, 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0x8a, 0xda, 0x25, 0x2c, 0xb9, 0x00, 187 | 0x00, 0x00, 188 | } 189 | -------------------------------------------------------------------------------- /14/grpc/bench/multi/grpcWithETCD/server1/vendor.conf: -------------------------------------------------------------------------------- 1 | # package 2 | github.com/linxGnu/meetup/14/grpc/bench/single/protobuf/server 3 | 4 | # import 5 | github.com/coreos/etcd v3.3.0-rc.0-1213-g62dfb89a8 6 | github.com/coreos/go-systemd v16-42-gd1b7d05 7 | github.com/coreos/pkg v3-13-g97fdf19 8 | github.com/gogo/protobuf v1.0.0-14-g1ef32a8b 9 | github.com/golang/protobuf v1.1.0 10 | go.uber.org/atomic v1.3.2 11 | go.uber.org/multierr v1.1.0-2-gddea229 12 | go.uber.org/zap v1.8.0-2-g2dc8d10 13 | golang.org/x/net 640f462 14 | golang.org/x/text v0.3.0-47-g7922cc4 15 | google.golang.org/genproto 86e600f 16 | google.golang.org/grpc v1.8.1-161-ge944391 17 | -------------------------------------------------------------------------------- /14/grpc/bench/multi/grpcWithETCD/server2/app.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "net" 7 | "os" 8 | "os/signal" 9 | "strings" 10 | "sync" 11 | "syscall" 12 | "time" 13 | 14 | etcdClient "github.com/coreos/etcd/clientv3" 15 | etcdnaming "github.com/coreos/etcd/clientv3/naming" 16 | grpc "google.golang.org/grpc" 17 | naming "google.golang.org/grpc/naming" 18 | ) 19 | 20 | const ( 21 | publicIP = "127.0.0.1" 22 | publicPort = 9904 23 | serviceName = "helloService" 24 | ) 25 | 26 | func main() { 27 | // os signal handling 28 | sigs := make(chan os.Signal, 10) 29 | signal.Notify(sigs, syscall.SIGINT, syscall.SIGQUIT, syscall.SIGKILL, syscall.SIGTERM, syscall.SIGSTOP, syscall.SIGTSTP, syscall.SIGEMT) 30 | 31 | // get etcd client 32 | cli, _ := getETCDClient() 33 | 34 | // try to listening to bind address 35 | listen, err := net.Listen("tcp", fmt.Sprintf(":%d", publicPort)) 36 | if err != nil { 37 | return 38 | } 39 | s := grpc.NewServer() 40 | RegisterHelloServer(s, &helloServer{}) 41 | 42 | go func() { 43 | if e := s.Serve(listen); e != nil { 44 | panic(e) 45 | } 46 | }() 47 | 48 | // keep alive with etcd 49 | kch, wg := make(chan struct{}, 1), sync.WaitGroup{} 50 | wg.Add(1) 51 | go func() { 52 | defer wg.Done() 53 | 54 | for { 55 | select { 56 | case <-kch: 57 | return 58 | default: 59 | time.Sleep(10 * time.Millisecond) 60 | } 61 | 62 | ctx, cancel := context.WithTimeout(context.Background(), 50*time.Millisecond) 63 | lease, er := cli.Grant(ctx, 1) 64 | if er != nil || lease == nil { 65 | cancel() 66 | fmt.Println(er) 67 | continue 68 | } 69 | <-ctx.Done() 70 | cancel() 71 | 72 | // attach key with lease 73 | ctx, cancel = context.WithTimeout(context.Background(), 50*time.Millisecond) 74 | resolver := &etcdnaming.GRPCResolver{Client: cli} 75 | if er = resolver.Update(ctx, serviceName, naming.Update{ 76 | Op: naming.Add, 77 | Addr: fmt.Sprintf("%s:%d", publicIP, publicPort), 78 | }, etcdClient.WithLease(lease.ID)); er != nil { 79 | cancel() 80 | fmt.Println(er) 81 | continue 82 | } 83 | <-ctx.Done() 84 | cancel() 85 | 86 | // keep a live lease 87 | keepAliveCh, er := cli.KeepAlive(context.Background(), lease.ID) 88 | if er != nil { 89 | fmt.Println(er) 90 | continue 91 | } 92 | 93 | L: 94 | for { 95 | select { 96 | case rp, opened := <-keepAliveCh: 97 | // The returned "LeaseKeepAliveResponse" channel closes if underlying keep 98 | // alive stream is interrupted in some way the client cannot handle itself; 99 | // given context "ctx" is canceled or timed out. "LeaseKeepAliveResponse" 100 | // from this closed channel is nil. 101 | if rp == nil || !opened { 102 | break L 103 | } 104 | case <-kch: 105 | return 106 | } 107 | } 108 | } 109 | }() 110 | 111 | <-sigs 112 | 113 | // notify we need to stop 114 | kch <- struct{}{} 115 | 116 | // Stop server now 117 | s.Stop() 118 | } 119 | 120 | func getETCDClient() (*etcdClient.Client, error) { 121 | return etcdClient.New(etcdClient.Config{ 122 | Endpoints: strings.Split("http://127.0.0.1:2379", ","), // etcd endpoints 123 | }) 124 | } 125 | 126 | type helloServer struct{} 127 | 128 | func (c *helloServer) SayHi(ctx context.Context, req *Payload) (resp *Payload, err error) { 129 | return req, nil 130 | } 131 | -------------------------------------------------------------------------------- /14/grpc/bench/multi/grpcWithETCD/server2/common.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-gogo. DO NOT EDIT. 2 | // source: common.proto 3 | 4 | /* 5 | Package main is a generated protocol buffer package. 6 | 7 | It is generated from these files: 8 | common.proto 9 | 10 | It has these top-level messages: 11 | Payload 12 | */ 13 | package main 14 | 15 | import proto "github.com/gogo/protobuf/proto" 16 | import fmt "fmt" 17 | import math "math" 18 | 19 | import context "golang.org/x/net/context" 20 | import grpc "google.golang.org/grpc" 21 | 22 | // Reference imports to suppress errors if they are not otherwise used. 23 | var _ = proto.Marshal 24 | var _ = fmt.Errorf 25 | var _ = math.Inf 26 | 27 | // This is a compile-time assertion to ensure that this generated file 28 | // is compatible with the proto package it is being compiled against. 29 | // A compilation error at this line likely means your copy of the 30 | // proto package needs to be updated. 31 | const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package 32 | 33 | type Payload struct { 34 | A string `protobuf:"bytes,1,opt,name=A,proto3" json:"A,omitempty"` 35 | B string `protobuf:"bytes,2,opt,name=B,proto3" json:"B,omitempty"` 36 | C int32 `protobuf:"varint,3,opt,name=C,proto3" json:"C,omitempty"` 37 | D string `protobuf:"bytes,4,opt,name=D,proto3" json:"D,omitempty"` 38 | E bool `protobuf:"varint,5,opt,name=E,proto3" json:"E,omitempty"` 39 | F int64 `protobuf:"varint,6,opt,name=F,proto3" json:"F,omitempty"` 40 | G string `protobuf:"bytes,7,opt,name=G,proto3" json:"G,omitempty"` 41 | } 42 | 43 | func (m *Payload) Reset() { *m = Payload{} } 44 | func (m *Payload) String() string { return proto.CompactTextString(m) } 45 | func (*Payload) ProtoMessage() {} 46 | func (*Payload) Descriptor() ([]byte, []int) { return fileDescriptorCommon, []int{0} } 47 | 48 | func (m *Payload) GetA() string { 49 | if m != nil { 50 | return m.A 51 | } 52 | return "" 53 | } 54 | 55 | func (m *Payload) GetB() string { 56 | if m != nil { 57 | return m.B 58 | } 59 | return "" 60 | } 61 | 62 | func (m *Payload) GetC() int32 { 63 | if m != nil { 64 | return m.C 65 | } 66 | return 0 67 | } 68 | 69 | func (m *Payload) GetD() string { 70 | if m != nil { 71 | return m.D 72 | } 73 | return "" 74 | } 75 | 76 | func (m *Payload) GetE() bool { 77 | if m != nil { 78 | return m.E 79 | } 80 | return false 81 | } 82 | 83 | func (m *Payload) GetF() int64 { 84 | if m != nil { 85 | return m.F 86 | } 87 | return 0 88 | } 89 | 90 | func (m *Payload) GetG() string { 91 | if m != nil { 92 | return m.G 93 | } 94 | return "" 95 | } 96 | 97 | func init() { 98 | proto.RegisterType((*Payload)(nil), "main.Payload") 99 | } 100 | 101 | // Reference imports to suppress errors if they are not otherwise used. 102 | var _ context.Context 103 | var _ grpc.ClientConn 104 | 105 | // This is a compile-time assertion to ensure that this generated file 106 | // is compatible with the grpc package it is being compiled against. 107 | const _ = grpc.SupportPackageIsVersion4 108 | 109 | // Client API for Hello service 110 | 111 | type HelloClient interface { 112 | SayHi(ctx context.Context, in *Payload, opts ...grpc.CallOption) (*Payload, error) 113 | } 114 | 115 | type helloClient struct { 116 | cc *grpc.ClientConn 117 | } 118 | 119 | func NewHelloClient(cc *grpc.ClientConn) HelloClient { 120 | return &helloClient{cc} 121 | } 122 | 123 | func (c *helloClient) SayHi(ctx context.Context, in *Payload, opts ...grpc.CallOption) (*Payload, error) { 124 | out := new(Payload) 125 | err := grpc.Invoke(ctx, "/main.Hello/SayHi", in, out, c.cc, opts...) 126 | if err != nil { 127 | return nil, err 128 | } 129 | return out, nil 130 | } 131 | 132 | // Server API for Hello service 133 | 134 | type HelloServer interface { 135 | SayHi(context.Context, *Payload) (*Payload, error) 136 | } 137 | 138 | func RegisterHelloServer(s *grpc.Server, srv HelloServer) { 139 | s.RegisterService(&_Hello_serviceDesc, srv) 140 | } 141 | 142 | func _Hello_SayHi_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 143 | in := new(Payload) 144 | if err := dec(in); err != nil { 145 | return nil, err 146 | } 147 | if interceptor == nil { 148 | return srv.(HelloServer).SayHi(ctx, in) 149 | } 150 | info := &grpc.UnaryServerInfo{ 151 | Server: srv, 152 | FullMethod: "/main.Hello/SayHi", 153 | } 154 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 155 | return srv.(HelloServer).SayHi(ctx, req.(*Payload)) 156 | } 157 | return interceptor(ctx, in, info, handler) 158 | } 159 | 160 | var _Hello_serviceDesc = grpc.ServiceDesc{ 161 | ServiceName: "main.Hello", 162 | HandlerType: (*HelloServer)(nil), 163 | Methods: []grpc.MethodDesc{ 164 | { 165 | MethodName: "SayHi", 166 | Handler: _Hello_SayHi_Handler, 167 | }, 168 | }, 169 | Streams: []grpc.StreamDesc{}, 170 | Metadata: "common.proto", 171 | } 172 | 173 | func init() { proto.RegisterFile("common.proto", fileDescriptorCommon) } 174 | 175 | var fileDescriptorCommon = []byte{ 176 | // 162 bytes of a gzipped FileDescriptorProto 177 | 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x49, 0xce, 0xcf, 0xcd, 178 | 0xcd, 0xcf, 0xd3, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0xc9, 0x4d, 0xcc, 0xcc, 0x53, 0xca, 179 | 0xe6, 0x62, 0x0f, 0x48, 0xac, 0xcc, 0xc9, 0x4f, 0x4c, 0x11, 0xe2, 0xe1, 0x62, 0x74, 0x94, 0x60, 180 | 0x54, 0x60, 0xd4, 0xe0, 0x0c, 0x62, 0x74, 0x04, 0xf1, 0x9c, 0x24, 0x98, 0x20, 0x3c, 0x27, 0x10, 181 | 0xcf, 0x59, 0x82, 0x59, 0x81, 0x51, 0x83, 0x35, 0x88, 0xd1, 0x19, 0xc4, 0x73, 0x91, 0x60, 0x81, 182 | 0xc8, 0xb9, 0x80, 0x78, 0xae, 0x12, 0xac, 0x0a, 0x8c, 0x1a, 0x1c, 0x41, 0x8c, 0xae, 0x20, 0x9e, 183 | 0x9b, 0x04, 0x9b, 0x02, 0xa3, 0x06, 0x73, 0x10, 0xa3, 0x1b, 0x88, 0xe7, 0x2e, 0xc1, 0x0e, 0x51, 184 | 0xe9, 0x6e, 0xa4, 0xc7, 0xc5, 0xea, 0x91, 0x9a, 0x93, 0x93, 0x2f, 0xa4, 0xca, 0xc5, 0x1a, 0x9c, 185 | 0x58, 0xe9, 0x91, 0x29, 0xc4, 0xab, 0x07, 0x72, 0x85, 0x1e, 0xd4, 0x09, 0x52, 0xa8, 0xdc, 0x24, 186 | 0x36, 0xb0, 0x4b, 0x8d, 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0x8a, 0xda, 0x25, 0x2c, 0xb9, 0x00, 187 | 0x00, 0x00, 188 | } 189 | -------------------------------------------------------------------------------- /14/grpc/bench/multi/grpcWithETCD/server2/vendor.conf: -------------------------------------------------------------------------------- 1 | # package 2 | github.com/linxGnu/meetup/14/grpc/bench/single/protobuf/server 3 | 4 | # import 5 | github.com/coreos/etcd v3.3.0-rc.0-1213-g62dfb89a8 6 | github.com/coreos/go-systemd v16-42-gd1b7d05 7 | github.com/coreos/pkg v3-13-g97fdf19 8 | github.com/gogo/protobuf v1.0.0-14-g1ef32a8b 9 | github.com/golang/protobuf v1.1.0 10 | go.uber.org/atomic v1.3.2 11 | go.uber.org/multierr v1.1.0-2-gddea229 12 | go.uber.org/zap v1.8.0-2-g2dc8d10 13 | golang.org/x/net 640f462 14 | golang.org/x/text v0.3.0-47-g7922cc4 15 | google.golang.org/genproto 86e600f 16 | google.golang.org/grpc v1.8.1-161-ge944391 17 | -------------------------------------------------------------------------------- /14/grpc/bench/multi/grpcWithNginx/client/app.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "sync" 7 | "sync/atomic" 8 | "time" 9 | 10 | grpc "google.golang.org/grpc" 11 | ) 12 | 13 | var numWorker = 50 14 | var numRequest = 10000 15 | var successCounter uint64 16 | 17 | var hClient HelloClient 18 | 19 | var p = &Payload{ 20 | A: "12345678901234567890", 21 | B: "abcdefghijklmnopqus", 22 | C: 43545, 23 | D: "asgkasjeglkajsgjalsjdglaskdjglads", 24 | E: true, 25 | F: -135465748, 26 | G: "gejoiwbbbdfasaaaaaaaaaaaaaaaaa", 27 | } 28 | 29 | func main() { 30 | ch := make(chan struct{}, numWorker) 31 | 32 | // worker 33 | var wg sync.WaitGroup 34 | for i := 0; i < numWorker; i++ { 35 | wg.Add(1) 36 | go func() { 37 | for range ch { 38 | doTask() 39 | } 40 | wg.Done() 41 | }() 42 | } 43 | 44 | // init client 45 | conn, err := grpc.Dial("127.0.0.1:9999", grpc.WithInsecure()) 46 | if err != nil { 47 | return 48 | } 49 | hClient = NewHelloClient(conn) 50 | 51 | time.Sleep(2 * time.Second) 52 | 53 | start := time.Now() 54 | for i := 0; i < numRequest; i++ { 55 | ch <- struct{}{} 56 | } 57 | close(ch) 58 | wg.Wait() 59 | end := time.Now() 60 | 61 | fmt.Println(end.Sub(start).Seconds(), fmt.Sprintf("%d / %d", successCounter, numRequest)) 62 | } 63 | 64 | func doTask() { 65 | _, err := hClient.SayHi(context.Background(), p) 66 | if err != nil { 67 | return 68 | } 69 | 70 | atomic.AddUint64(&successCounter, 1) 71 | } 72 | -------------------------------------------------------------------------------- /14/grpc/bench/multi/grpcWithNginx/client/common.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-gogo. DO NOT EDIT. 2 | // source: common.proto 3 | 4 | /* 5 | Package main is a generated protocol buffer package. 6 | 7 | It is generated from these files: 8 | common.proto 9 | 10 | It has these top-level messages: 11 | Payload 12 | */ 13 | package main 14 | 15 | import proto "github.com/gogo/protobuf/proto" 16 | import fmt "fmt" 17 | import math "math" 18 | 19 | import context "golang.org/x/net/context" 20 | import grpc "google.golang.org/grpc" 21 | 22 | // Reference imports to suppress errors if they are not otherwise used. 23 | var _ = proto.Marshal 24 | var _ = fmt.Errorf 25 | var _ = math.Inf 26 | 27 | // This is a compile-time assertion to ensure that this generated file 28 | // is compatible with the proto package it is being compiled against. 29 | // A compilation error at this line likely means your copy of the 30 | // proto package needs to be updated. 31 | const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package 32 | 33 | type Payload struct { 34 | A string `protobuf:"bytes,1,opt,name=A,proto3" json:"A,omitempty"` 35 | B string `protobuf:"bytes,2,opt,name=B,proto3" json:"B,omitempty"` 36 | C int32 `protobuf:"varint,3,opt,name=C,proto3" json:"C,omitempty"` 37 | D string `protobuf:"bytes,4,opt,name=D,proto3" json:"D,omitempty"` 38 | E bool `protobuf:"varint,5,opt,name=E,proto3" json:"E,omitempty"` 39 | F int64 `protobuf:"varint,6,opt,name=F,proto3" json:"F,omitempty"` 40 | G string `protobuf:"bytes,7,opt,name=G,proto3" json:"G,omitempty"` 41 | } 42 | 43 | func (m *Payload) Reset() { *m = Payload{} } 44 | func (m *Payload) String() string { return proto.CompactTextString(m) } 45 | func (*Payload) ProtoMessage() {} 46 | func (*Payload) Descriptor() ([]byte, []int) { return fileDescriptorCommon, []int{0} } 47 | 48 | func (m *Payload) GetA() string { 49 | if m != nil { 50 | return m.A 51 | } 52 | return "" 53 | } 54 | 55 | func (m *Payload) GetB() string { 56 | if m != nil { 57 | return m.B 58 | } 59 | return "" 60 | } 61 | 62 | func (m *Payload) GetC() int32 { 63 | if m != nil { 64 | return m.C 65 | } 66 | return 0 67 | } 68 | 69 | func (m *Payload) GetD() string { 70 | if m != nil { 71 | return m.D 72 | } 73 | return "" 74 | } 75 | 76 | func (m *Payload) GetE() bool { 77 | if m != nil { 78 | return m.E 79 | } 80 | return false 81 | } 82 | 83 | func (m *Payload) GetF() int64 { 84 | if m != nil { 85 | return m.F 86 | } 87 | return 0 88 | } 89 | 90 | func (m *Payload) GetG() string { 91 | if m != nil { 92 | return m.G 93 | } 94 | return "" 95 | } 96 | 97 | func init() { 98 | proto.RegisterType((*Payload)(nil), "main.Payload") 99 | } 100 | 101 | // Reference imports to suppress errors if they are not otherwise used. 102 | var _ context.Context 103 | var _ grpc.ClientConn 104 | 105 | // This is a compile-time assertion to ensure that this generated file 106 | // is compatible with the grpc package it is being compiled against. 107 | const _ = grpc.SupportPackageIsVersion4 108 | 109 | // Client API for Hello service 110 | 111 | type HelloClient interface { 112 | SayHi(ctx context.Context, in *Payload, opts ...grpc.CallOption) (*Payload, error) 113 | } 114 | 115 | type helloClient struct { 116 | cc *grpc.ClientConn 117 | } 118 | 119 | func NewHelloClient(cc *grpc.ClientConn) HelloClient { 120 | return &helloClient{cc} 121 | } 122 | 123 | func (c *helloClient) SayHi(ctx context.Context, in *Payload, opts ...grpc.CallOption) (*Payload, error) { 124 | out := new(Payload) 125 | err := grpc.Invoke(ctx, "/main.Hello/SayHi", in, out, c.cc, opts...) 126 | if err != nil { 127 | return nil, err 128 | } 129 | return out, nil 130 | } 131 | 132 | // Server API for Hello service 133 | 134 | type HelloServer interface { 135 | SayHi(context.Context, *Payload) (*Payload, error) 136 | } 137 | 138 | func RegisterHelloServer(s *grpc.Server, srv HelloServer) { 139 | s.RegisterService(&_Hello_serviceDesc, srv) 140 | } 141 | 142 | func _Hello_SayHi_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 143 | in := new(Payload) 144 | if err := dec(in); err != nil { 145 | return nil, err 146 | } 147 | if interceptor == nil { 148 | return srv.(HelloServer).SayHi(ctx, in) 149 | } 150 | info := &grpc.UnaryServerInfo{ 151 | Server: srv, 152 | FullMethod: "/main.Hello/SayHi", 153 | } 154 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 155 | return srv.(HelloServer).SayHi(ctx, req.(*Payload)) 156 | } 157 | return interceptor(ctx, in, info, handler) 158 | } 159 | 160 | var _Hello_serviceDesc = grpc.ServiceDesc{ 161 | ServiceName: "main.Hello", 162 | HandlerType: (*HelloServer)(nil), 163 | Methods: []grpc.MethodDesc{ 164 | { 165 | MethodName: "SayHi", 166 | Handler: _Hello_SayHi_Handler, 167 | }, 168 | }, 169 | Streams: []grpc.StreamDesc{}, 170 | Metadata: "common.proto", 171 | } 172 | 173 | func init() { proto.RegisterFile("common.proto", fileDescriptorCommon) } 174 | 175 | var fileDescriptorCommon = []byte{ 176 | // 162 bytes of a gzipped FileDescriptorProto 177 | 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x49, 0xce, 0xcf, 0xcd, 178 | 0xcd, 0xcf, 0xd3, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0xc9, 0x4d, 0xcc, 0xcc, 0x53, 0xca, 179 | 0xe6, 0x62, 0x0f, 0x48, 0xac, 0xcc, 0xc9, 0x4f, 0x4c, 0x11, 0xe2, 0xe1, 0x62, 0x74, 0x94, 0x60, 180 | 0x54, 0x60, 0xd4, 0xe0, 0x0c, 0x62, 0x74, 0x04, 0xf1, 0x9c, 0x24, 0x98, 0x20, 0x3c, 0x27, 0x10, 181 | 0xcf, 0x59, 0x82, 0x59, 0x81, 0x51, 0x83, 0x35, 0x88, 0xd1, 0x19, 0xc4, 0x73, 0x91, 0x60, 0x81, 182 | 0xc8, 0xb9, 0x80, 0x78, 0xae, 0x12, 0xac, 0x0a, 0x8c, 0x1a, 0x1c, 0x41, 0x8c, 0xae, 0x20, 0x9e, 183 | 0x9b, 0x04, 0x9b, 0x02, 0xa3, 0x06, 0x73, 0x10, 0xa3, 0x1b, 0x88, 0xe7, 0x2e, 0xc1, 0x0e, 0x51, 184 | 0xe9, 0x6e, 0xa4, 0xc7, 0xc5, 0xea, 0x91, 0x9a, 0x93, 0x93, 0x2f, 0xa4, 0xca, 0xc5, 0x1a, 0x9c, 185 | 0x58, 0xe9, 0x91, 0x29, 0xc4, 0xab, 0x07, 0x72, 0x85, 0x1e, 0xd4, 0x09, 0x52, 0xa8, 0xdc, 0x24, 186 | 0x36, 0xb0, 0x4b, 0x8d, 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0x8a, 0xda, 0x25, 0x2c, 0xb9, 0x00, 187 | 0x00, 0x00, 188 | } 189 | -------------------------------------------------------------------------------- /14/grpc/bench/multi/grpcWithNginx/protos/common.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-gogo. DO NOT EDIT. 2 | // source: common.proto 3 | 4 | /* 5 | Package main is a generated protocol buffer package. 6 | 7 | It is generated from these files: 8 | common.proto 9 | 10 | It has these top-level messages: 11 | Payload 12 | */ 13 | package main 14 | 15 | import proto "github.com/gogo/protobuf/proto" 16 | import fmt "fmt" 17 | import math "math" 18 | 19 | import context "golang.org/x/net/context" 20 | import grpc "google.golang.org/grpc" 21 | 22 | // Reference imports to suppress errors if they are not otherwise used. 23 | var _ = proto.Marshal 24 | var _ = fmt.Errorf 25 | var _ = math.Inf 26 | 27 | // This is a compile-time assertion to ensure that this generated file 28 | // is compatible with the proto package it is being compiled against. 29 | // A compilation error at this line likely means your copy of the 30 | // proto package needs to be updated. 31 | const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package 32 | 33 | type Payload struct { 34 | A string `protobuf:"bytes,1,opt,name=A,proto3" json:"A,omitempty"` 35 | B string `protobuf:"bytes,2,opt,name=B,proto3" json:"B,omitempty"` 36 | C int32 `protobuf:"varint,3,opt,name=C,proto3" json:"C,omitempty"` 37 | D string `protobuf:"bytes,4,opt,name=D,proto3" json:"D,omitempty"` 38 | E bool `protobuf:"varint,5,opt,name=E,proto3" json:"E,omitempty"` 39 | F int64 `protobuf:"varint,6,opt,name=F,proto3" json:"F,omitempty"` 40 | G string `protobuf:"bytes,7,opt,name=G,proto3" json:"G,omitempty"` 41 | } 42 | 43 | func (m *Payload) Reset() { *m = Payload{} } 44 | func (m *Payload) String() string { return proto.CompactTextString(m) } 45 | func (*Payload) ProtoMessage() {} 46 | func (*Payload) Descriptor() ([]byte, []int) { return fileDescriptorCommon, []int{0} } 47 | 48 | func (m *Payload) GetA() string { 49 | if m != nil { 50 | return m.A 51 | } 52 | return "" 53 | } 54 | 55 | func (m *Payload) GetB() string { 56 | if m != nil { 57 | return m.B 58 | } 59 | return "" 60 | } 61 | 62 | func (m *Payload) GetC() int32 { 63 | if m != nil { 64 | return m.C 65 | } 66 | return 0 67 | } 68 | 69 | func (m *Payload) GetD() string { 70 | if m != nil { 71 | return m.D 72 | } 73 | return "" 74 | } 75 | 76 | func (m *Payload) GetE() bool { 77 | if m != nil { 78 | return m.E 79 | } 80 | return false 81 | } 82 | 83 | func (m *Payload) GetF() int64 { 84 | if m != nil { 85 | return m.F 86 | } 87 | return 0 88 | } 89 | 90 | func (m *Payload) GetG() string { 91 | if m != nil { 92 | return m.G 93 | } 94 | return "" 95 | } 96 | 97 | func init() { 98 | proto.RegisterType((*Payload)(nil), "main.Payload") 99 | } 100 | 101 | // Reference imports to suppress errors if they are not otherwise used. 102 | var _ context.Context 103 | var _ grpc.ClientConn 104 | 105 | // This is a compile-time assertion to ensure that this generated file 106 | // is compatible with the grpc package it is being compiled against. 107 | const _ = grpc.SupportPackageIsVersion4 108 | 109 | // Client API for Hello service 110 | 111 | type HelloClient interface { 112 | SayHi(ctx context.Context, in *Payload, opts ...grpc.CallOption) (*Payload, error) 113 | } 114 | 115 | type helloClient struct { 116 | cc *grpc.ClientConn 117 | } 118 | 119 | func NewHelloClient(cc *grpc.ClientConn) HelloClient { 120 | return &helloClient{cc} 121 | } 122 | 123 | func (c *helloClient) SayHi(ctx context.Context, in *Payload, opts ...grpc.CallOption) (*Payload, error) { 124 | out := new(Payload) 125 | err := grpc.Invoke(ctx, "/main.Hello/SayHi", in, out, c.cc, opts...) 126 | if err != nil { 127 | return nil, err 128 | } 129 | return out, nil 130 | } 131 | 132 | // Server API for Hello service 133 | 134 | type HelloServer interface { 135 | SayHi(context.Context, *Payload) (*Payload, error) 136 | } 137 | 138 | func RegisterHelloServer(s *grpc.Server, srv HelloServer) { 139 | s.RegisterService(&_Hello_serviceDesc, srv) 140 | } 141 | 142 | func _Hello_SayHi_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 143 | in := new(Payload) 144 | if err := dec(in); err != nil { 145 | return nil, err 146 | } 147 | if interceptor == nil { 148 | return srv.(HelloServer).SayHi(ctx, in) 149 | } 150 | info := &grpc.UnaryServerInfo{ 151 | Server: srv, 152 | FullMethod: "/main.Hello/SayHi", 153 | } 154 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 155 | return srv.(HelloServer).SayHi(ctx, req.(*Payload)) 156 | } 157 | return interceptor(ctx, in, info, handler) 158 | } 159 | 160 | var _Hello_serviceDesc = grpc.ServiceDesc{ 161 | ServiceName: "main.Hello", 162 | HandlerType: (*HelloServer)(nil), 163 | Methods: []grpc.MethodDesc{ 164 | { 165 | MethodName: "SayHi", 166 | Handler: _Hello_SayHi_Handler, 167 | }, 168 | }, 169 | Streams: []grpc.StreamDesc{}, 170 | Metadata: "common.proto", 171 | } 172 | 173 | func init() { proto.RegisterFile("common.proto", fileDescriptorCommon) } 174 | 175 | var fileDescriptorCommon = []byte{ 176 | // 162 bytes of a gzipped FileDescriptorProto 177 | 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x49, 0xce, 0xcf, 0xcd, 178 | 0xcd, 0xcf, 0xd3, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0xc9, 0x4d, 0xcc, 0xcc, 0x53, 0xca, 179 | 0xe6, 0x62, 0x0f, 0x48, 0xac, 0xcc, 0xc9, 0x4f, 0x4c, 0x11, 0xe2, 0xe1, 0x62, 0x74, 0x94, 0x60, 180 | 0x54, 0x60, 0xd4, 0xe0, 0x0c, 0x62, 0x74, 0x04, 0xf1, 0x9c, 0x24, 0x98, 0x20, 0x3c, 0x27, 0x10, 181 | 0xcf, 0x59, 0x82, 0x59, 0x81, 0x51, 0x83, 0x35, 0x88, 0xd1, 0x19, 0xc4, 0x73, 0x91, 0x60, 0x81, 182 | 0xc8, 0xb9, 0x80, 0x78, 0xae, 0x12, 0xac, 0x0a, 0x8c, 0x1a, 0x1c, 0x41, 0x8c, 0xae, 0x20, 0x9e, 183 | 0x9b, 0x04, 0x9b, 0x02, 0xa3, 0x06, 0x73, 0x10, 0xa3, 0x1b, 0x88, 0xe7, 0x2e, 0xc1, 0x0e, 0x51, 184 | 0xe9, 0x6e, 0xa4, 0xc7, 0xc5, 0xea, 0x91, 0x9a, 0x93, 0x93, 0x2f, 0xa4, 0xca, 0xc5, 0x1a, 0x9c, 185 | 0x58, 0xe9, 0x91, 0x29, 0xc4, 0xab, 0x07, 0x72, 0x85, 0x1e, 0xd4, 0x09, 0x52, 0xa8, 0xdc, 0x24, 186 | 0x36, 0xb0, 0x4b, 0x8d, 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0x8a, 0xda, 0x25, 0x2c, 0xb9, 0x00, 187 | 0x00, 0x00, 188 | } 189 | -------------------------------------------------------------------------------- /14/grpc/bench/multi/grpcWithNginx/protos/common.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package main; 4 | 5 | service Hello { 6 | rpc SayHi(Payload) returns (Payload); 7 | } 8 | 9 | message Payload { 10 | string A = 1; 11 | string B = 2; 12 | int32 C = 3; 13 | string D = 4; 14 | bool E = 5; 15 | int64 F = 6; 16 | string G = 7; 17 | } -------------------------------------------------------------------------------- /14/grpc/bench/multi/grpcWithNginx/protos/gen.sh: -------------------------------------------------------------------------------- 1 | 2 | #!/bin/bash 3 | my_dir=`dirname $0` 4 | 5 | protoc -I=$my_dir -I=$GOPATH/src -I=$GOPATH/src/github.com/gogo/protobuf/protobuf --gogo_out=plugins=grpc:$my_dir/ $my_dir/*.proto -------------------------------------------------------------------------------- /14/grpc/bench/multi/grpcWithNginx/server1/app.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "net" 7 | 8 | grpc "google.golang.org/grpc" 9 | ) 10 | 11 | func main() { 12 | // try to listening to bind address 13 | listen, err := net.Listen("tcp", fmt.Sprintf(":%d", 9903)) 14 | if err != nil { 15 | return 16 | } 17 | s := grpc.NewServer() 18 | RegisterHelloServer(s, &helloServer{}) 19 | 20 | if e := s.Serve(listen); e != nil { 21 | panic(e) 22 | } 23 | } 24 | 25 | type helloServer struct{} 26 | 27 | func (c *helloServer) SayHi(ctx context.Context, req *Payload) (resp *Payload, err error) { 28 | return req, nil 29 | } 30 | -------------------------------------------------------------------------------- /14/grpc/bench/multi/grpcWithNginx/server1/common.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-gogo. DO NOT EDIT. 2 | // source: common.proto 3 | 4 | /* 5 | Package main is a generated protocol buffer package. 6 | 7 | It is generated from these files: 8 | common.proto 9 | 10 | It has these top-level messages: 11 | Payload 12 | */ 13 | package main 14 | 15 | import proto "github.com/gogo/protobuf/proto" 16 | import fmt "fmt" 17 | import math "math" 18 | 19 | import context "golang.org/x/net/context" 20 | import grpc "google.golang.org/grpc" 21 | 22 | // Reference imports to suppress errors if they are not otherwise used. 23 | var _ = proto.Marshal 24 | var _ = fmt.Errorf 25 | var _ = math.Inf 26 | 27 | // This is a compile-time assertion to ensure that this generated file 28 | // is compatible with the proto package it is being compiled against. 29 | // A compilation error at this line likely means your copy of the 30 | // proto package needs to be updated. 31 | const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package 32 | 33 | type Payload struct { 34 | A string `protobuf:"bytes,1,opt,name=A,proto3" json:"A,omitempty"` 35 | B string `protobuf:"bytes,2,opt,name=B,proto3" json:"B,omitempty"` 36 | C int32 `protobuf:"varint,3,opt,name=C,proto3" json:"C,omitempty"` 37 | D string `protobuf:"bytes,4,opt,name=D,proto3" json:"D,omitempty"` 38 | E bool `protobuf:"varint,5,opt,name=E,proto3" json:"E,omitempty"` 39 | F int64 `protobuf:"varint,6,opt,name=F,proto3" json:"F,omitempty"` 40 | G string `protobuf:"bytes,7,opt,name=G,proto3" json:"G,omitempty"` 41 | } 42 | 43 | func (m *Payload) Reset() { *m = Payload{} } 44 | func (m *Payload) String() string { return proto.CompactTextString(m) } 45 | func (*Payload) ProtoMessage() {} 46 | func (*Payload) Descriptor() ([]byte, []int) { return fileDescriptorCommon, []int{0} } 47 | 48 | func (m *Payload) GetA() string { 49 | if m != nil { 50 | return m.A 51 | } 52 | return "" 53 | } 54 | 55 | func (m *Payload) GetB() string { 56 | if m != nil { 57 | return m.B 58 | } 59 | return "" 60 | } 61 | 62 | func (m *Payload) GetC() int32 { 63 | if m != nil { 64 | return m.C 65 | } 66 | return 0 67 | } 68 | 69 | func (m *Payload) GetD() string { 70 | if m != nil { 71 | return m.D 72 | } 73 | return "" 74 | } 75 | 76 | func (m *Payload) GetE() bool { 77 | if m != nil { 78 | return m.E 79 | } 80 | return false 81 | } 82 | 83 | func (m *Payload) GetF() int64 { 84 | if m != nil { 85 | return m.F 86 | } 87 | return 0 88 | } 89 | 90 | func (m *Payload) GetG() string { 91 | if m != nil { 92 | return m.G 93 | } 94 | return "" 95 | } 96 | 97 | func init() { 98 | proto.RegisterType((*Payload)(nil), "main.Payload") 99 | } 100 | 101 | // Reference imports to suppress errors if they are not otherwise used. 102 | var _ context.Context 103 | var _ grpc.ClientConn 104 | 105 | // This is a compile-time assertion to ensure that this generated file 106 | // is compatible with the grpc package it is being compiled against. 107 | const _ = grpc.SupportPackageIsVersion4 108 | 109 | // Client API for Hello service 110 | 111 | type HelloClient interface { 112 | SayHi(ctx context.Context, in *Payload, opts ...grpc.CallOption) (*Payload, error) 113 | } 114 | 115 | type helloClient struct { 116 | cc *grpc.ClientConn 117 | } 118 | 119 | func NewHelloClient(cc *grpc.ClientConn) HelloClient { 120 | return &helloClient{cc} 121 | } 122 | 123 | func (c *helloClient) SayHi(ctx context.Context, in *Payload, opts ...grpc.CallOption) (*Payload, error) { 124 | out := new(Payload) 125 | err := grpc.Invoke(ctx, "/main.Hello/SayHi", in, out, c.cc, opts...) 126 | if err != nil { 127 | return nil, err 128 | } 129 | return out, nil 130 | } 131 | 132 | // Server API for Hello service 133 | 134 | type HelloServer interface { 135 | SayHi(context.Context, *Payload) (*Payload, error) 136 | } 137 | 138 | func RegisterHelloServer(s *grpc.Server, srv HelloServer) { 139 | s.RegisterService(&_Hello_serviceDesc, srv) 140 | } 141 | 142 | func _Hello_SayHi_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 143 | in := new(Payload) 144 | if err := dec(in); err != nil { 145 | return nil, err 146 | } 147 | if interceptor == nil { 148 | return srv.(HelloServer).SayHi(ctx, in) 149 | } 150 | info := &grpc.UnaryServerInfo{ 151 | Server: srv, 152 | FullMethod: "/main.Hello/SayHi", 153 | } 154 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 155 | return srv.(HelloServer).SayHi(ctx, req.(*Payload)) 156 | } 157 | return interceptor(ctx, in, info, handler) 158 | } 159 | 160 | var _Hello_serviceDesc = grpc.ServiceDesc{ 161 | ServiceName: "main.Hello", 162 | HandlerType: (*HelloServer)(nil), 163 | Methods: []grpc.MethodDesc{ 164 | { 165 | MethodName: "SayHi", 166 | Handler: _Hello_SayHi_Handler, 167 | }, 168 | }, 169 | Streams: []grpc.StreamDesc{}, 170 | Metadata: "common.proto", 171 | } 172 | 173 | func init() { proto.RegisterFile("common.proto", fileDescriptorCommon) } 174 | 175 | var fileDescriptorCommon = []byte{ 176 | // 162 bytes of a gzipped FileDescriptorProto 177 | 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x49, 0xce, 0xcf, 0xcd, 178 | 0xcd, 0xcf, 0xd3, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0xc9, 0x4d, 0xcc, 0xcc, 0x53, 0xca, 179 | 0xe6, 0x62, 0x0f, 0x48, 0xac, 0xcc, 0xc9, 0x4f, 0x4c, 0x11, 0xe2, 0xe1, 0x62, 0x74, 0x94, 0x60, 180 | 0x54, 0x60, 0xd4, 0xe0, 0x0c, 0x62, 0x74, 0x04, 0xf1, 0x9c, 0x24, 0x98, 0x20, 0x3c, 0x27, 0x10, 181 | 0xcf, 0x59, 0x82, 0x59, 0x81, 0x51, 0x83, 0x35, 0x88, 0xd1, 0x19, 0xc4, 0x73, 0x91, 0x60, 0x81, 182 | 0xc8, 0xb9, 0x80, 0x78, 0xae, 0x12, 0xac, 0x0a, 0x8c, 0x1a, 0x1c, 0x41, 0x8c, 0xae, 0x20, 0x9e, 183 | 0x9b, 0x04, 0x9b, 0x02, 0xa3, 0x06, 0x73, 0x10, 0xa3, 0x1b, 0x88, 0xe7, 0x2e, 0xc1, 0x0e, 0x51, 184 | 0xe9, 0x6e, 0xa4, 0xc7, 0xc5, 0xea, 0x91, 0x9a, 0x93, 0x93, 0x2f, 0xa4, 0xca, 0xc5, 0x1a, 0x9c, 185 | 0x58, 0xe9, 0x91, 0x29, 0xc4, 0xab, 0x07, 0x72, 0x85, 0x1e, 0xd4, 0x09, 0x52, 0xa8, 0xdc, 0x24, 186 | 0x36, 0xb0, 0x4b, 0x8d, 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0x8a, 0xda, 0x25, 0x2c, 0xb9, 0x00, 187 | 0x00, 0x00, 188 | } 189 | -------------------------------------------------------------------------------- /14/grpc/bench/multi/grpcWithNginx/server1/vendor.conf: -------------------------------------------------------------------------------- 1 | # package 2 | github.com/linxGnu/meetup/14/grpc/bench/single/protobuf/server 3 | 4 | # import 5 | github.com/gogo/protobuf v1.0.0-14-g1ef32a8b 6 | github.com/golang/protobuf v1.1.0 7 | golang.org/x/net 640f462 8 | golang.org/x/text v0.3.0-47-g7922cc4 9 | google.golang.org/genproto 86e600f 10 | google.golang.org/grpc v1.8.1-161-ge944391 11 | -------------------------------------------------------------------------------- /14/grpc/bench/multi/grpcWithNginx/server2/app.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "net" 7 | 8 | grpc "google.golang.org/grpc" 9 | ) 10 | 11 | func main() { 12 | // try to listening to bind address 13 | listen, err := net.Listen("tcp", fmt.Sprintf(":%d", 9904)) 14 | if err != nil { 15 | return 16 | } 17 | s := grpc.NewServer() 18 | RegisterHelloServer(s, &helloServer{}) 19 | 20 | if e := s.Serve(listen); e != nil { 21 | panic(e) 22 | } 23 | } 24 | 25 | type helloServer struct{} 26 | 27 | func (c *helloServer) SayHi(ctx context.Context, req *Payload) (resp *Payload, err error) { 28 | return req, nil 29 | } 30 | -------------------------------------------------------------------------------- /14/grpc/bench/multi/grpcWithNginx/server2/common.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-gogo. DO NOT EDIT. 2 | // source: common.proto 3 | 4 | /* 5 | Package main is a generated protocol buffer package. 6 | 7 | It is generated from these files: 8 | common.proto 9 | 10 | It has these top-level messages: 11 | Payload 12 | */ 13 | package main 14 | 15 | import proto "github.com/gogo/protobuf/proto" 16 | import fmt "fmt" 17 | import math "math" 18 | 19 | import context "golang.org/x/net/context" 20 | import grpc "google.golang.org/grpc" 21 | 22 | // Reference imports to suppress errors if they are not otherwise used. 23 | var _ = proto.Marshal 24 | var _ = fmt.Errorf 25 | var _ = math.Inf 26 | 27 | // This is a compile-time assertion to ensure that this generated file 28 | // is compatible with the proto package it is being compiled against. 29 | // A compilation error at this line likely means your copy of the 30 | // proto package needs to be updated. 31 | const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package 32 | 33 | type Payload struct { 34 | A string `protobuf:"bytes,1,opt,name=A,proto3" json:"A,omitempty"` 35 | B string `protobuf:"bytes,2,opt,name=B,proto3" json:"B,omitempty"` 36 | C int32 `protobuf:"varint,3,opt,name=C,proto3" json:"C,omitempty"` 37 | D string `protobuf:"bytes,4,opt,name=D,proto3" json:"D,omitempty"` 38 | E bool `protobuf:"varint,5,opt,name=E,proto3" json:"E,omitempty"` 39 | F int64 `protobuf:"varint,6,opt,name=F,proto3" json:"F,omitempty"` 40 | G string `protobuf:"bytes,7,opt,name=G,proto3" json:"G,omitempty"` 41 | } 42 | 43 | func (m *Payload) Reset() { *m = Payload{} } 44 | func (m *Payload) String() string { return proto.CompactTextString(m) } 45 | func (*Payload) ProtoMessage() {} 46 | func (*Payload) Descriptor() ([]byte, []int) { return fileDescriptorCommon, []int{0} } 47 | 48 | func (m *Payload) GetA() string { 49 | if m != nil { 50 | return m.A 51 | } 52 | return "" 53 | } 54 | 55 | func (m *Payload) GetB() string { 56 | if m != nil { 57 | return m.B 58 | } 59 | return "" 60 | } 61 | 62 | func (m *Payload) GetC() int32 { 63 | if m != nil { 64 | return m.C 65 | } 66 | return 0 67 | } 68 | 69 | func (m *Payload) GetD() string { 70 | if m != nil { 71 | return m.D 72 | } 73 | return "" 74 | } 75 | 76 | func (m *Payload) GetE() bool { 77 | if m != nil { 78 | return m.E 79 | } 80 | return false 81 | } 82 | 83 | func (m *Payload) GetF() int64 { 84 | if m != nil { 85 | return m.F 86 | } 87 | return 0 88 | } 89 | 90 | func (m *Payload) GetG() string { 91 | if m != nil { 92 | return m.G 93 | } 94 | return "" 95 | } 96 | 97 | func init() { 98 | proto.RegisterType((*Payload)(nil), "main.Payload") 99 | } 100 | 101 | // Reference imports to suppress errors if they are not otherwise used. 102 | var _ context.Context 103 | var _ grpc.ClientConn 104 | 105 | // This is a compile-time assertion to ensure that this generated file 106 | // is compatible with the grpc package it is being compiled against. 107 | const _ = grpc.SupportPackageIsVersion4 108 | 109 | // Client API for Hello service 110 | 111 | type HelloClient interface { 112 | SayHi(ctx context.Context, in *Payload, opts ...grpc.CallOption) (*Payload, error) 113 | } 114 | 115 | type helloClient struct { 116 | cc *grpc.ClientConn 117 | } 118 | 119 | func NewHelloClient(cc *grpc.ClientConn) HelloClient { 120 | return &helloClient{cc} 121 | } 122 | 123 | func (c *helloClient) SayHi(ctx context.Context, in *Payload, opts ...grpc.CallOption) (*Payload, error) { 124 | out := new(Payload) 125 | err := grpc.Invoke(ctx, "/main.Hello/SayHi", in, out, c.cc, opts...) 126 | if err != nil { 127 | return nil, err 128 | } 129 | return out, nil 130 | } 131 | 132 | // Server API for Hello service 133 | 134 | type HelloServer interface { 135 | SayHi(context.Context, *Payload) (*Payload, error) 136 | } 137 | 138 | func RegisterHelloServer(s *grpc.Server, srv HelloServer) { 139 | s.RegisterService(&_Hello_serviceDesc, srv) 140 | } 141 | 142 | func _Hello_SayHi_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 143 | in := new(Payload) 144 | if err := dec(in); err != nil { 145 | return nil, err 146 | } 147 | if interceptor == nil { 148 | return srv.(HelloServer).SayHi(ctx, in) 149 | } 150 | info := &grpc.UnaryServerInfo{ 151 | Server: srv, 152 | FullMethod: "/main.Hello/SayHi", 153 | } 154 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 155 | return srv.(HelloServer).SayHi(ctx, req.(*Payload)) 156 | } 157 | return interceptor(ctx, in, info, handler) 158 | } 159 | 160 | var _Hello_serviceDesc = grpc.ServiceDesc{ 161 | ServiceName: "main.Hello", 162 | HandlerType: (*HelloServer)(nil), 163 | Methods: []grpc.MethodDesc{ 164 | { 165 | MethodName: "SayHi", 166 | Handler: _Hello_SayHi_Handler, 167 | }, 168 | }, 169 | Streams: []grpc.StreamDesc{}, 170 | Metadata: "common.proto", 171 | } 172 | 173 | func init() { proto.RegisterFile("common.proto", fileDescriptorCommon) } 174 | 175 | var fileDescriptorCommon = []byte{ 176 | // 162 bytes of a gzipped FileDescriptorProto 177 | 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x49, 0xce, 0xcf, 0xcd, 178 | 0xcd, 0xcf, 0xd3, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0xc9, 0x4d, 0xcc, 0xcc, 0x53, 0xca, 179 | 0xe6, 0x62, 0x0f, 0x48, 0xac, 0xcc, 0xc9, 0x4f, 0x4c, 0x11, 0xe2, 0xe1, 0x62, 0x74, 0x94, 0x60, 180 | 0x54, 0x60, 0xd4, 0xe0, 0x0c, 0x62, 0x74, 0x04, 0xf1, 0x9c, 0x24, 0x98, 0x20, 0x3c, 0x27, 0x10, 181 | 0xcf, 0x59, 0x82, 0x59, 0x81, 0x51, 0x83, 0x35, 0x88, 0xd1, 0x19, 0xc4, 0x73, 0x91, 0x60, 0x81, 182 | 0xc8, 0xb9, 0x80, 0x78, 0xae, 0x12, 0xac, 0x0a, 0x8c, 0x1a, 0x1c, 0x41, 0x8c, 0xae, 0x20, 0x9e, 183 | 0x9b, 0x04, 0x9b, 0x02, 0xa3, 0x06, 0x73, 0x10, 0xa3, 0x1b, 0x88, 0xe7, 0x2e, 0xc1, 0x0e, 0x51, 184 | 0xe9, 0x6e, 0xa4, 0xc7, 0xc5, 0xea, 0x91, 0x9a, 0x93, 0x93, 0x2f, 0xa4, 0xca, 0xc5, 0x1a, 0x9c, 185 | 0x58, 0xe9, 0x91, 0x29, 0xc4, 0xab, 0x07, 0x72, 0x85, 0x1e, 0xd4, 0x09, 0x52, 0xa8, 0xdc, 0x24, 186 | 0x36, 0xb0, 0x4b, 0x8d, 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0x8a, 0xda, 0x25, 0x2c, 0xb9, 0x00, 187 | 0x00, 0x00, 188 | } 189 | -------------------------------------------------------------------------------- /14/grpc/bench/multi/grpcWithNginx/server2/vendor.conf: -------------------------------------------------------------------------------- 1 | # package 2 | github.com/linxGnu/meetup/14/grpc/bench/single/protobuf/server 3 | 4 | # import 5 | github.com/gogo/protobuf v1.0.0-14-g1ef32a8b 6 | github.com/golang/protobuf v1.1.0 7 | golang.org/x/net 640f462 8 | golang.org/x/text v0.3.0-47-g7922cc4 9 | google.golang.org/genproto 86e600f 10 | google.golang.org/grpc v1.8.1-161-ge944391 11 | -------------------------------------------------------------------------------- /14/grpc/bench/multi/json/client/app.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "encoding/json" 6 | "fmt" 7 | "net/http" 8 | "sync" 9 | "sync/atomic" 10 | "time" 11 | ) 12 | 13 | var numWorker = 50 14 | var numRequest = 1000000 15 | var successCounter uint64 16 | 17 | var tr = &http.Transport{ 18 | MaxIdleConnsPerHost: numWorker, 19 | } 20 | var httpClient = http.Client{Transport: tr} 21 | 22 | type payload struct { 23 | A string `json:"a"` 24 | B string `json:"b"` 25 | C int `json:"c"` 26 | D string `json:"d"` 27 | E bool `json:"e"` 28 | F int64 `json:"f"` 29 | G string `json:"g"` 30 | } 31 | 32 | var p = &payload{ 33 | A: "12345678901234567890", 34 | B: "abcdefghijklmnopqus", 35 | C: 43545, 36 | D: "asgkasjeglkajsgjalsjdglaskdjglads", 37 | E: true, 38 | F: -135465748, 39 | G: "gejoiwbbbdfasaaaaaaaaaaaaaaaaa", 40 | } 41 | 42 | func main() { 43 | ch := make(chan struct{}, numWorker) 44 | 45 | // worker 46 | var wg sync.WaitGroup 47 | for i := 0; i < numWorker; i++ { 48 | wg.Add(1) 49 | go func() { 50 | for range ch { 51 | doTask() 52 | } 53 | wg.Done() 54 | }() 55 | } 56 | 57 | start := time.Now() 58 | for i := 0; i < numRequest; i++ { 59 | ch <- struct{}{} 60 | } 61 | close(ch) 62 | wg.Wait() 63 | end := time.Now() 64 | 65 | fmt.Println(end.Sub(start).Seconds(), fmt.Sprintf("%d / %d", successCounter, numRequest)) 66 | } 67 | 68 | func doTask() { 69 | b := new(bytes.Buffer) 70 | if err := json.NewEncoder(b).Encode(p); err != nil { 71 | fmt.Println(err) 72 | return 73 | } 74 | 75 | resp, err := httpClient.Post("http://127.0.0.1:8888/hello", "application/json; charset=utf-8", b) 76 | if err != nil { 77 | fmt.Println(err) 78 | return 79 | } 80 | 81 | var tmp payload 82 | if err = json.NewDecoder(resp.Body).Decode(&tmp); err != nil { 83 | return 84 | } 85 | 86 | atomic.AddUint64(&successCounter, 1) 87 | } 88 | -------------------------------------------------------------------------------- /14/grpc/bench/multi/json/server1/app.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "net/http" 7 | 8 | "github.com/gorilla/mux" 9 | ) 10 | 11 | type payload struct { 12 | A string `json:"a"` 13 | B string `json:"b"` 14 | C int `json:"c"` 15 | D string `json:"d"` 16 | E bool `json:"e"` 17 | F int64 `json:"f"` 18 | G string `json:"g"` 19 | } 20 | 21 | func main() { 22 | router := mux.NewRouter().StrictSlash(true) 23 | 24 | router.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) { 25 | var data payload 26 | if r.Body == nil { 27 | http.Error(w, "Please send a request body", 400) 28 | return 29 | } 30 | if err := json.NewDecoder(r.Body).Decode(&data); err != nil { 31 | fmt.Println(err) 32 | http.Error(w, err.Error(), 400) 33 | return 34 | } 35 | 36 | pl, err := json.Marshal(data) 37 | if err != nil { 38 | fmt.Println(err) 39 | http.Error(w, err.Error(), 400) 40 | return 41 | } 42 | 43 | w.Header().Set("Content-Type", "application/json") 44 | w.Write(pl) 45 | }) 46 | 47 | http.ListenAndServe(":9901", router) 48 | } 49 | -------------------------------------------------------------------------------- /14/grpc/bench/multi/json/server1/vendor.conf: -------------------------------------------------------------------------------- 1 | # package 2 | github.com/linxGnu/meetup/14/grpc/bench/single/json/server 3 | 4 | # import 5 | github.com/gorilla/context v1.1-7-g08b5f42 6 | github.com/gorilla/mux v1.6.1-16-gded0c29 7 | -------------------------------------------------------------------------------- /14/grpc/bench/multi/json/server2/app.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "net/http" 7 | 8 | "github.com/gorilla/mux" 9 | ) 10 | 11 | type payload struct { 12 | A string `json:"a"` 13 | B string `json:"b"` 14 | C int `json:"c"` 15 | D string `json:"d"` 16 | E bool `json:"e"` 17 | F int64 `json:"f"` 18 | G string `json:"g"` 19 | } 20 | 21 | func main() { 22 | router := mux.NewRouter().StrictSlash(true) 23 | 24 | router.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) { 25 | var data payload 26 | if r.Body == nil { 27 | http.Error(w, "Please send a request body", 400) 28 | return 29 | } 30 | if err := json.NewDecoder(r.Body).Decode(&data); err != nil { 31 | fmt.Println(err) 32 | http.Error(w, err.Error(), 400) 33 | return 34 | } 35 | 36 | pl, err := json.Marshal(data) 37 | if err != nil { 38 | fmt.Println(err) 39 | http.Error(w, err.Error(), 400) 40 | return 41 | } 42 | 43 | w.Header().Set("Content-Type", "application/json") 44 | w.Write(pl) 45 | }) 46 | 47 | http.ListenAndServe(":9902", router) 48 | } 49 | -------------------------------------------------------------------------------- /14/grpc/bench/multi/json/server2/vendor.conf: -------------------------------------------------------------------------------- 1 | # package 2 | github.com/linxGnu/meetup/14/grpc/bench/single/json/server 3 | 4 | # import 5 | github.com/gorilla/context v1.1-7-g08b5f42 6 | github.com/gorilla/mux v1.6.1-16-gded0c29 7 | -------------------------------------------------------------------------------- /14/grpc/bench/multi/protobuf/client/app.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "io/ioutil" 7 | "net/http" 8 | "sync" 9 | "sync/atomic" 10 | "time" 11 | 12 | "github.com/golang/protobuf/proto" 13 | ) 14 | 15 | var numWorker = 50 16 | var numRequest = 1000000 17 | var successCounter uint64 18 | 19 | var tr = &http.Transport{ 20 | MaxIdleConnsPerHost: 200, 21 | } 22 | var httpClient = http.Client{Transport: tr} 23 | 24 | var p = &Payload{ 25 | A: "12345678901234567890", 26 | B: "abcdefghijklmnopqus", 27 | C: 43545, 28 | D: "asgkasjeglkajsgjalsjdglaskdjglads", 29 | E: true, 30 | F: -135465748, 31 | G: "gejoiwbbbdfasaaaaaaaaaaaaaaaaa", 32 | } 33 | 34 | func main() { 35 | ch := make(chan struct{}, numWorker) 36 | 37 | // worker 38 | var wg sync.WaitGroup 39 | for i := 0; i < numWorker; i++ { 40 | wg.Add(1) 41 | go func() { 42 | for range ch { 43 | doTask() 44 | } 45 | wg.Done() 46 | }() 47 | } 48 | 49 | start := time.Now() 50 | for i := 0; i < numRequest; i++ { 51 | ch <- struct{}{} 52 | } 53 | close(ch) 54 | wg.Wait() 55 | end := time.Now() 56 | 57 | fmt.Println(end.Sub(start).Seconds(), fmt.Sprintf("%d / %d", successCounter, numRequest)) 58 | } 59 | 60 | func doTask() { 61 | pl, err := proto.Marshal(p) 62 | if err != nil { 63 | return 64 | } 65 | 66 | resp, err := httpClient.Post("http://127.0.0.1:8888/hello", "application/protobuf", bytes.NewReader(pl)) 67 | if err != nil { 68 | return 69 | } 70 | 71 | buf, err := ioutil.ReadAll(resp.Body) 72 | if err != nil { 73 | return 74 | } 75 | 76 | var tmp Payload 77 | if err = proto.Unmarshal(buf, &tmp); err != nil { 78 | return 79 | } 80 | 81 | atomic.AddUint64(&successCounter, 1) 82 | } 83 | -------------------------------------------------------------------------------- /14/grpc/bench/multi/protobuf/client/common.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-gogo. DO NOT EDIT. 2 | // source: common.proto 3 | 4 | /* 5 | Package main is a generated protocol buffer package. 6 | 7 | It is generated from these files: 8 | common.proto 9 | 10 | It has these top-level messages: 11 | Payload 12 | */ 13 | package main 14 | 15 | import proto "github.com/gogo/protobuf/proto" 16 | import fmt "fmt" 17 | import math "math" 18 | 19 | // Reference imports to suppress errors if they are not otherwise used. 20 | var _ = proto.Marshal 21 | var _ = fmt.Errorf 22 | var _ = math.Inf 23 | 24 | // This is a compile-time assertion to ensure that this generated file 25 | // is compatible with the proto package it is being compiled against. 26 | // A compilation error at this line likely means your copy of the 27 | // proto package needs to be updated. 28 | const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package 29 | 30 | type Payload struct { 31 | A string `protobuf:"bytes,1,opt,name=A,proto3" json:"A,omitempty"` 32 | B string `protobuf:"bytes,2,opt,name=B,proto3" json:"B,omitempty"` 33 | C int32 `protobuf:"varint,3,opt,name=C,proto3" json:"C,omitempty"` 34 | D string `protobuf:"bytes,4,opt,name=D,proto3" json:"D,omitempty"` 35 | E bool `protobuf:"varint,5,opt,name=E,proto3" json:"E,omitempty"` 36 | F int64 `protobuf:"varint,6,opt,name=F,proto3" json:"F,omitempty"` 37 | G string `protobuf:"bytes,7,opt,name=G,proto3" json:"G,omitempty"` 38 | } 39 | 40 | func (m *Payload) Reset() { *m = Payload{} } 41 | func (m *Payload) String() string { return proto.CompactTextString(m) } 42 | func (*Payload) ProtoMessage() {} 43 | func (*Payload) Descriptor() ([]byte, []int) { return fileDescriptorCommon, []int{0} } 44 | 45 | func (m *Payload) GetA() string { 46 | if m != nil { 47 | return m.A 48 | } 49 | return "" 50 | } 51 | 52 | func (m *Payload) GetB() string { 53 | if m != nil { 54 | return m.B 55 | } 56 | return "" 57 | } 58 | 59 | func (m *Payload) GetC() int32 { 60 | if m != nil { 61 | return m.C 62 | } 63 | return 0 64 | } 65 | 66 | func (m *Payload) GetD() string { 67 | if m != nil { 68 | return m.D 69 | } 70 | return "" 71 | } 72 | 73 | func (m *Payload) GetE() bool { 74 | if m != nil { 75 | return m.E 76 | } 77 | return false 78 | } 79 | 80 | func (m *Payload) GetF() int64 { 81 | if m != nil { 82 | return m.F 83 | } 84 | return 0 85 | } 86 | 87 | func (m *Payload) GetG() string { 88 | if m != nil { 89 | return m.G 90 | } 91 | return "" 92 | } 93 | 94 | func init() { 95 | proto.RegisterType((*Payload)(nil), "main.Payload") 96 | } 97 | 98 | func init() { proto.RegisterFile("common.proto", fileDescriptorCommon) } 99 | 100 | var fileDescriptorCommon = []byte{ 101 | // 132 bytes of a gzipped FileDescriptorProto 102 | 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x49, 0xce, 0xcf, 0xcd, 103 | 0xcd, 0xcf, 0xd3, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0xc9, 0x4d, 0xcc, 0xcc, 0x53, 0xca, 104 | 0xe6, 0x62, 0x0f, 0x48, 0xac, 0xcc, 0xc9, 0x4f, 0x4c, 0x11, 0xe2, 0xe1, 0x62, 0x74, 0x94, 0x60, 105 | 0x54, 0x60, 0xd4, 0xe0, 0x0c, 0x62, 0x74, 0x04, 0xf1, 0x9c, 0x24, 0x98, 0x20, 0x3c, 0x27, 0x10, 106 | 0xcf, 0x59, 0x82, 0x59, 0x81, 0x51, 0x83, 0x35, 0x88, 0xd1, 0x19, 0xc4, 0x73, 0x91, 0x60, 0x81, 107 | 0xc8, 0xb9, 0x80, 0x78, 0xae, 0x12, 0xac, 0x0a, 0x8c, 0x1a, 0x1c, 0x41, 0x8c, 0xae, 0x20, 0x9e, 108 | 0x9b, 0x04, 0x9b, 0x02, 0xa3, 0x06, 0x73, 0x10, 0xa3, 0x1b, 0x88, 0xe7, 0x2e, 0xc1, 0x0e, 0x51, 109 | 0xe9, 0x9e, 0xc4, 0x06, 0xb6, 0xd9, 0x18, 0x10, 0x00, 0x00, 0xff, 0xff, 0xdd, 0x66, 0x6f, 0x2b, 110 | 0x89, 0x00, 0x00, 0x00, 111 | } 112 | -------------------------------------------------------------------------------- /14/grpc/bench/multi/protobuf/client/vendor.conf: -------------------------------------------------------------------------------- 1 | # package 2 | github.com/linxGnu/meetup/14/grpc/bench/single/protobuf/client 3 | 4 | # import 5 | github.com/gogo/protobuf v1.0.0-14-g1ef32a8b 6 | github.com/golang/protobuf v1.1.0 7 | -------------------------------------------------------------------------------- /14/grpc/bench/multi/protobuf/protos/common.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-gogo. DO NOT EDIT. 2 | // source: common.proto 3 | 4 | /* 5 | Package main is a generated protocol buffer package. 6 | 7 | It is generated from these files: 8 | common.proto 9 | 10 | It has these top-level messages: 11 | Payload 12 | */ 13 | package main 14 | 15 | import proto "github.com/gogo/protobuf/proto" 16 | import fmt "fmt" 17 | import math "math" 18 | 19 | // Reference imports to suppress errors if they are not otherwise used. 20 | var _ = proto.Marshal 21 | var _ = fmt.Errorf 22 | var _ = math.Inf 23 | 24 | // This is a compile-time assertion to ensure that this generated file 25 | // is compatible with the proto package it is being compiled against. 26 | // A compilation error at this line likely means your copy of the 27 | // proto package needs to be updated. 28 | const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package 29 | 30 | type Payload struct { 31 | A string `protobuf:"bytes,1,opt,name=A,proto3" json:"A,omitempty"` 32 | B string `protobuf:"bytes,2,opt,name=B,proto3" json:"B,omitempty"` 33 | C int32 `protobuf:"varint,3,opt,name=C,proto3" json:"C,omitempty"` 34 | D string `protobuf:"bytes,4,opt,name=D,proto3" json:"D,omitempty"` 35 | E bool `protobuf:"varint,5,opt,name=E,proto3" json:"E,omitempty"` 36 | F int64 `protobuf:"varint,6,opt,name=F,proto3" json:"F,omitempty"` 37 | G string `protobuf:"bytes,7,opt,name=G,proto3" json:"G,omitempty"` 38 | } 39 | 40 | func (m *Payload) Reset() { *m = Payload{} } 41 | func (m *Payload) String() string { return proto.CompactTextString(m) } 42 | func (*Payload) ProtoMessage() {} 43 | func (*Payload) Descriptor() ([]byte, []int) { return fileDescriptorCommon, []int{0} } 44 | 45 | func (m *Payload) GetA() string { 46 | if m != nil { 47 | return m.A 48 | } 49 | return "" 50 | } 51 | 52 | func (m *Payload) GetB() string { 53 | if m != nil { 54 | return m.B 55 | } 56 | return "" 57 | } 58 | 59 | func (m *Payload) GetC() int32 { 60 | if m != nil { 61 | return m.C 62 | } 63 | return 0 64 | } 65 | 66 | func (m *Payload) GetD() string { 67 | if m != nil { 68 | return m.D 69 | } 70 | return "" 71 | } 72 | 73 | func (m *Payload) GetE() bool { 74 | if m != nil { 75 | return m.E 76 | } 77 | return false 78 | } 79 | 80 | func (m *Payload) GetF() int64 { 81 | if m != nil { 82 | return m.F 83 | } 84 | return 0 85 | } 86 | 87 | func (m *Payload) GetG() string { 88 | if m != nil { 89 | return m.G 90 | } 91 | return "" 92 | } 93 | 94 | func init() { 95 | proto.RegisterType((*Payload)(nil), "main.Payload") 96 | } 97 | 98 | func init() { proto.RegisterFile("common.proto", fileDescriptorCommon) } 99 | 100 | var fileDescriptorCommon = []byte{ 101 | // 132 bytes of a gzipped FileDescriptorProto 102 | 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x49, 0xce, 0xcf, 0xcd, 103 | 0xcd, 0xcf, 0xd3, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0xc9, 0x4d, 0xcc, 0xcc, 0x53, 0xca, 104 | 0xe6, 0x62, 0x0f, 0x48, 0xac, 0xcc, 0xc9, 0x4f, 0x4c, 0x11, 0xe2, 0xe1, 0x62, 0x74, 0x94, 0x60, 105 | 0x54, 0x60, 0xd4, 0xe0, 0x0c, 0x62, 0x74, 0x04, 0xf1, 0x9c, 0x24, 0x98, 0x20, 0x3c, 0x27, 0x10, 106 | 0xcf, 0x59, 0x82, 0x59, 0x81, 0x51, 0x83, 0x35, 0x88, 0xd1, 0x19, 0xc4, 0x73, 0x91, 0x60, 0x81, 107 | 0xc8, 0xb9, 0x80, 0x78, 0xae, 0x12, 0xac, 0x0a, 0x8c, 0x1a, 0x1c, 0x41, 0x8c, 0xae, 0x20, 0x9e, 108 | 0x9b, 0x04, 0x9b, 0x02, 0xa3, 0x06, 0x73, 0x10, 0xa3, 0x1b, 0x88, 0xe7, 0x2e, 0xc1, 0x0e, 0x51, 109 | 0xe9, 0x9e, 0xc4, 0x06, 0xb6, 0xd9, 0x18, 0x10, 0x00, 0x00, 0xff, 0xff, 0xdd, 0x66, 0x6f, 0x2b, 110 | 0x89, 0x00, 0x00, 0x00, 111 | } 112 | -------------------------------------------------------------------------------- /14/grpc/bench/multi/protobuf/protos/common.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package main; 4 | 5 | message Payload { 6 | string A = 1; 7 | string B = 2; 8 | int32 C = 3; 9 | string D = 4; 10 | bool E = 5; 11 | int64 F = 6; 12 | string G = 7; 13 | } -------------------------------------------------------------------------------- /14/grpc/bench/multi/protobuf/protos/gen.sh: -------------------------------------------------------------------------------- 1 | 2 | #!/bin/bash 3 | my_dir=`dirname $0` 4 | 5 | protoc -I=$my_dir -I=$GOPATH/src -I=$GOPATH/src/github.com/gogo/protobuf/protobuf --gogo_out=$my_dir/ $my_dir/*.proto -------------------------------------------------------------------------------- /14/grpc/bench/multi/protobuf/server1/app.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io/ioutil" 6 | "net/http" 7 | 8 | "github.com/golang/protobuf/proto" 9 | "github.com/gorilla/mux" 10 | ) 11 | 12 | func main() { 13 | router := mux.NewRouter().StrictSlash(true) 14 | 15 | router.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) { 16 | if r.Body == nil { 17 | http.Error(w, "Please send a request body", 400) 18 | return 19 | } 20 | 21 | buf, err := ioutil.ReadAll(r.Body) 22 | if err != nil { 23 | fmt.Println(err) 24 | http.Error(w, err.Error(), 400) 25 | return 26 | } 27 | 28 | var data Payload 29 | if err := proto.Unmarshal(buf, &data); err != nil { 30 | fmt.Println(err) 31 | http.Error(w, err.Error(), 400) 32 | return 33 | } 34 | 35 | pl, err := proto.Marshal(&data) 36 | if err != nil { 37 | fmt.Println(err) 38 | http.Error(w, err.Error(), 400) 39 | return 40 | } 41 | 42 | w.Header().Set("Content-Type", "application/protobuf") 43 | w.Write(pl) 44 | }) 45 | 46 | http.ListenAndServe(":9901", router) 47 | } 48 | -------------------------------------------------------------------------------- /14/grpc/bench/multi/protobuf/server1/common.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-gogo. DO NOT EDIT. 2 | // source: common.proto 3 | 4 | /* 5 | Package main is a generated protocol buffer package. 6 | 7 | It is generated from these files: 8 | common.proto 9 | 10 | It has these top-level messages: 11 | Payload 12 | */ 13 | package main 14 | 15 | import proto "github.com/gogo/protobuf/proto" 16 | import fmt "fmt" 17 | import math "math" 18 | 19 | // Reference imports to suppress errors if they are not otherwise used. 20 | var _ = proto.Marshal 21 | var _ = fmt.Errorf 22 | var _ = math.Inf 23 | 24 | // This is a compile-time assertion to ensure that this generated file 25 | // is compatible with the proto package it is being compiled against. 26 | // A compilation error at this line likely means your copy of the 27 | // proto package needs to be updated. 28 | const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package 29 | 30 | type Payload struct { 31 | A string `protobuf:"bytes,1,opt,name=A,proto3" json:"A,omitempty"` 32 | B string `protobuf:"bytes,2,opt,name=B,proto3" json:"B,omitempty"` 33 | C int32 `protobuf:"varint,3,opt,name=C,proto3" json:"C,omitempty"` 34 | D string `protobuf:"bytes,4,opt,name=D,proto3" json:"D,omitempty"` 35 | E bool `protobuf:"varint,5,opt,name=E,proto3" json:"E,omitempty"` 36 | F int64 `protobuf:"varint,6,opt,name=F,proto3" json:"F,omitempty"` 37 | G string `protobuf:"bytes,7,opt,name=G,proto3" json:"G,omitempty"` 38 | } 39 | 40 | func (m *Payload) Reset() { *m = Payload{} } 41 | func (m *Payload) String() string { return proto.CompactTextString(m) } 42 | func (*Payload) ProtoMessage() {} 43 | func (*Payload) Descriptor() ([]byte, []int) { return fileDescriptorCommon, []int{0} } 44 | 45 | func (m *Payload) GetA() string { 46 | if m != nil { 47 | return m.A 48 | } 49 | return "" 50 | } 51 | 52 | func (m *Payload) GetB() string { 53 | if m != nil { 54 | return m.B 55 | } 56 | return "" 57 | } 58 | 59 | func (m *Payload) GetC() int32 { 60 | if m != nil { 61 | return m.C 62 | } 63 | return 0 64 | } 65 | 66 | func (m *Payload) GetD() string { 67 | if m != nil { 68 | return m.D 69 | } 70 | return "" 71 | } 72 | 73 | func (m *Payload) GetE() bool { 74 | if m != nil { 75 | return m.E 76 | } 77 | return false 78 | } 79 | 80 | func (m *Payload) GetF() int64 { 81 | if m != nil { 82 | return m.F 83 | } 84 | return 0 85 | } 86 | 87 | func (m *Payload) GetG() string { 88 | if m != nil { 89 | return m.G 90 | } 91 | return "" 92 | } 93 | 94 | func init() { 95 | proto.RegisterType((*Payload)(nil), "main.Payload") 96 | } 97 | 98 | func init() { proto.RegisterFile("common.proto", fileDescriptorCommon) } 99 | 100 | var fileDescriptorCommon = []byte{ 101 | // 132 bytes of a gzipped FileDescriptorProto 102 | 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x49, 0xce, 0xcf, 0xcd, 103 | 0xcd, 0xcf, 0xd3, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0xc9, 0x4d, 0xcc, 0xcc, 0x53, 0xca, 104 | 0xe6, 0x62, 0x0f, 0x48, 0xac, 0xcc, 0xc9, 0x4f, 0x4c, 0x11, 0xe2, 0xe1, 0x62, 0x74, 0x94, 0x60, 105 | 0x54, 0x60, 0xd4, 0xe0, 0x0c, 0x62, 0x74, 0x04, 0xf1, 0x9c, 0x24, 0x98, 0x20, 0x3c, 0x27, 0x10, 106 | 0xcf, 0x59, 0x82, 0x59, 0x81, 0x51, 0x83, 0x35, 0x88, 0xd1, 0x19, 0xc4, 0x73, 0x91, 0x60, 0x81, 107 | 0xc8, 0xb9, 0x80, 0x78, 0xae, 0x12, 0xac, 0x0a, 0x8c, 0x1a, 0x1c, 0x41, 0x8c, 0xae, 0x20, 0x9e, 108 | 0x9b, 0x04, 0x9b, 0x02, 0xa3, 0x06, 0x73, 0x10, 0xa3, 0x1b, 0x88, 0xe7, 0x2e, 0xc1, 0x0e, 0x51, 109 | 0xe9, 0x9e, 0xc4, 0x06, 0xb6, 0xd9, 0x18, 0x10, 0x00, 0x00, 0xff, 0xff, 0xdd, 0x66, 0x6f, 0x2b, 110 | 0x89, 0x00, 0x00, 0x00, 111 | } 112 | -------------------------------------------------------------------------------- /14/grpc/bench/multi/protobuf/server1/vendor.conf: -------------------------------------------------------------------------------- 1 | # package 2 | github.com/linxGnu/meetup/14/grpc/bench/single/protobuf/server 3 | 4 | # import 5 | github.com/golang/protobuf v1.1.0 6 | github.com/gorilla/context v1.1-7-g08b5f42 7 | github.com/gorilla/mux v1.6.1-16-gded0c29 8 | -------------------------------------------------------------------------------- /14/grpc/bench/multi/protobuf/server2/app.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io/ioutil" 6 | "net/http" 7 | 8 | "github.com/golang/protobuf/proto" 9 | "github.com/gorilla/mux" 10 | ) 11 | 12 | func main() { 13 | router := mux.NewRouter().StrictSlash(true) 14 | 15 | router.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) { 16 | if r.Body == nil { 17 | http.Error(w, "Please send a request body", 400) 18 | return 19 | } 20 | 21 | buf, err := ioutil.ReadAll(r.Body) 22 | if err != nil { 23 | fmt.Println(err) 24 | http.Error(w, err.Error(), 400) 25 | return 26 | } 27 | 28 | var data Payload 29 | if err := proto.Unmarshal(buf, &data); err != nil { 30 | fmt.Println(err) 31 | http.Error(w, err.Error(), 400) 32 | return 33 | } 34 | 35 | pl, err := proto.Marshal(&data) 36 | if err != nil { 37 | fmt.Println(err) 38 | http.Error(w, err.Error(), 400) 39 | return 40 | } 41 | 42 | w.Header().Set("Content-Type", "application/protobuf") 43 | w.Write(pl) 44 | }) 45 | 46 | http.ListenAndServe(":9902", router) 47 | } 48 | -------------------------------------------------------------------------------- /14/grpc/bench/multi/protobuf/server2/common.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-gogo. DO NOT EDIT. 2 | // source: common.proto 3 | 4 | /* 5 | Package main is a generated protocol buffer package. 6 | 7 | It is generated from these files: 8 | common.proto 9 | 10 | It has these top-level messages: 11 | Payload 12 | */ 13 | package main 14 | 15 | import proto "github.com/gogo/protobuf/proto" 16 | import fmt "fmt" 17 | import math "math" 18 | 19 | // Reference imports to suppress errors if they are not otherwise used. 20 | var _ = proto.Marshal 21 | var _ = fmt.Errorf 22 | var _ = math.Inf 23 | 24 | // This is a compile-time assertion to ensure that this generated file 25 | // is compatible with the proto package it is being compiled against. 26 | // A compilation error at this line likely means your copy of the 27 | // proto package needs to be updated. 28 | const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package 29 | 30 | type Payload struct { 31 | A string `protobuf:"bytes,1,opt,name=A,proto3" json:"A,omitempty"` 32 | B string `protobuf:"bytes,2,opt,name=B,proto3" json:"B,omitempty"` 33 | C int32 `protobuf:"varint,3,opt,name=C,proto3" json:"C,omitempty"` 34 | D string `protobuf:"bytes,4,opt,name=D,proto3" json:"D,omitempty"` 35 | E bool `protobuf:"varint,5,opt,name=E,proto3" json:"E,omitempty"` 36 | F int64 `protobuf:"varint,6,opt,name=F,proto3" json:"F,omitempty"` 37 | G string `protobuf:"bytes,7,opt,name=G,proto3" json:"G,omitempty"` 38 | } 39 | 40 | func (m *Payload) Reset() { *m = Payload{} } 41 | func (m *Payload) String() string { return proto.CompactTextString(m) } 42 | func (*Payload) ProtoMessage() {} 43 | func (*Payload) Descriptor() ([]byte, []int) { return fileDescriptorCommon, []int{0} } 44 | 45 | func (m *Payload) GetA() string { 46 | if m != nil { 47 | return m.A 48 | } 49 | return "" 50 | } 51 | 52 | func (m *Payload) GetB() string { 53 | if m != nil { 54 | return m.B 55 | } 56 | return "" 57 | } 58 | 59 | func (m *Payload) GetC() int32 { 60 | if m != nil { 61 | return m.C 62 | } 63 | return 0 64 | } 65 | 66 | func (m *Payload) GetD() string { 67 | if m != nil { 68 | return m.D 69 | } 70 | return "" 71 | } 72 | 73 | func (m *Payload) GetE() bool { 74 | if m != nil { 75 | return m.E 76 | } 77 | return false 78 | } 79 | 80 | func (m *Payload) GetF() int64 { 81 | if m != nil { 82 | return m.F 83 | } 84 | return 0 85 | } 86 | 87 | func (m *Payload) GetG() string { 88 | if m != nil { 89 | return m.G 90 | } 91 | return "" 92 | } 93 | 94 | func init() { 95 | proto.RegisterType((*Payload)(nil), "main.Payload") 96 | } 97 | 98 | func init() { proto.RegisterFile("common.proto", fileDescriptorCommon) } 99 | 100 | var fileDescriptorCommon = []byte{ 101 | // 132 bytes of a gzipped FileDescriptorProto 102 | 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x49, 0xce, 0xcf, 0xcd, 103 | 0xcd, 0xcf, 0xd3, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0xc9, 0x4d, 0xcc, 0xcc, 0x53, 0xca, 104 | 0xe6, 0x62, 0x0f, 0x48, 0xac, 0xcc, 0xc9, 0x4f, 0x4c, 0x11, 0xe2, 0xe1, 0x62, 0x74, 0x94, 0x60, 105 | 0x54, 0x60, 0xd4, 0xe0, 0x0c, 0x62, 0x74, 0x04, 0xf1, 0x9c, 0x24, 0x98, 0x20, 0x3c, 0x27, 0x10, 106 | 0xcf, 0x59, 0x82, 0x59, 0x81, 0x51, 0x83, 0x35, 0x88, 0xd1, 0x19, 0xc4, 0x73, 0x91, 0x60, 0x81, 107 | 0xc8, 0xb9, 0x80, 0x78, 0xae, 0x12, 0xac, 0x0a, 0x8c, 0x1a, 0x1c, 0x41, 0x8c, 0xae, 0x20, 0x9e, 108 | 0x9b, 0x04, 0x9b, 0x02, 0xa3, 0x06, 0x73, 0x10, 0xa3, 0x1b, 0x88, 0xe7, 0x2e, 0xc1, 0x0e, 0x51, 109 | 0xe9, 0x9e, 0xc4, 0x06, 0xb6, 0xd9, 0x18, 0x10, 0x00, 0x00, 0xff, 0xff, 0xdd, 0x66, 0x6f, 0x2b, 110 | 0x89, 0x00, 0x00, 0x00, 111 | } 112 | -------------------------------------------------------------------------------- /14/grpc/bench/multi/protobuf/server2/vendor.conf: -------------------------------------------------------------------------------- 1 | # package 2 | github.com/linxGnu/meetup/14/grpc/bench/single/protobuf/server 3 | 4 | # import 5 | github.com/golang/protobuf v1.1.0 6 | github.com/gorilla/context v1.1-7-g08b5f42 7 | github.com/gorilla/mux v1.6.1-16-gded0c29 8 | -------------------------------------------------------------------------------- /14/grpc/bench/single/grpc/client/app.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "sync" 7 | "sync/atomic" 8 | "time" 9 | 10 | grpc "google.golang.org/grpc" 11 | ) 12 | 13 | var numWorker = 50 14 | var numRequest = 1000000 15 | var successCounter uint64 16 | 17 | var hClient HelloClient 18 | 19 | var p = &Payload{ 20 | A: "12345678901234567890", 21 | B: "abcdefghijklmnopqus", 22 | C: 43545, 23 | D: "asgkasjeglkajsgjalsjdglaskdjglads", 24 | E: true, 25 | F: -135465748, 26 | G: "gejoiwbbbdfasaaaaaaaaaaaaaaaaa", 27 | } 28 | 29 | func main() { 30 | ch := make(chan struct{}, numWorker) 31 | 32 | // worker 33 | var wg sync.WaitGroup 34 | for i := 0; i < numWorker; i++ { 35 | wg.Add(1) 36 | go func() { 37 | for range ch { 38 | doTask() 39 | } 40 | wg.Done() 41 | }() 42 | } 43 | 44 | // init client 45 | conn, err := grpc.Dial("127.0.0.1:7777", grpc.WithInsecure()) 46 | if err != nil { 47 | return 48 | } 49 | hClient = NewHelloClient(conn) 50 | 51 | start := time.Now() 52 | for i := 0; i < numRequest; i++ { 53 | ch <- struct{}{} 54 | } 55 | close(ch) 56 | wg.Wait() 57 | end := time.Now() 58 | 59 | fmt.Println(end.Sub(start).Seconds(), fmt.Sprintf("%d / %d", successCounter, numRequest)) 60 | } 61 | 62 | func doTask() { 63 | _, err := hClient.SayHi(context.Background(), p) 64 | if err != nil { 65 | return 66 | } 67 | 68 | atomic.AddUint64(&successCounter, 1) 69 | } 70 | -------------------------------------------------------------------------------- /14/grpc/bench/single/grpc/client/common.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-gogo. DO NOT EDIT. 2 | // source: common.proto 3 | 4 | /* 5 | Package main is a generated protocol buffer package. 6 | 7 | It is generated from these files: 8 | common.proto 9 | 10 | It has these top-level messages: 11 | Payload 12 | */ 13 | package main 14 | 15 | import proto "github.com/gogo/protobuf/proto" 16 | import fmt "fmt" 17 | import math "math" 18 | 19 | import context "golang.org/x/net/context" 20 | import grpc "google.golang.org/grpc" 21 | 22 | // Reference imports to suppress errors if they are not otherwise used. 23 | var _ = proto.Marshal 24 | var _ = fmt.Errorf 25 | var _ = math.Inf 26 | 27 | // This is a compile-time assertion to ensure that this generated file 28 | // is compatible with the proto package it is being compiled against. 29 | // A compilation error at this line likely means your copy of the 30 | // proto package needs to be updated. 31 | const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package 32 | 33 | type Payload struct { 34 | A string `protobuf:"bytes,1,opt,name=A,proto3" json:"A,omitempty"` 35 | B string `protobuf:"bytes,2,opt,name=B,proto3" json:"B,omitempty"` 36 | C int32 `protobuf:"varint,3,opt,name=C,proto3" json:"C,omitempty"` 37 | D string `protobuf:"bytes,4,opt,name=D,proto3" json:"D,omitempty"` 38 | E bool `protobuf:"varint,5,opt,name=E,proto3" json:"E,omitempty"` 39 | F int64 `protobuf:"varint,6,opt,name=F,proto3" json:"F,omitempty"` 40 | G string `protobuf:"bytes,7,opt,name=G,proto3" json:"G,omitempty"` 41 | } 42 | 43 | func (m *Payload) Reset() { *m = Payload{} } 44 | func (m *Payload) String() string { return proto.CompactTextString(m) } 45 | func (*Payload) ProtoMessage() {} 46 | func (*Payload) Descriptor() ([]byte, []int) { return fileDescriptorCommon, []int{0} } 47 | 48 | func (m *Payload) GetA() string { 49 | if m != nil { 50 | return m.A 51 | } 52 | return "" 53 | } 54 | 55 | func (m *Payload) GetB() string { 56 | if m != nil { 57 | return m.B 58 | } 59 | return "" 60 | } 61 | 62 | func (m *Payload) GetC() int32 { 63 | if m != nil { 64 | return m.C 65 | } 66 | return 0 67 | } 68 | 69 | func (m *Payload) GetD() string { 70 | if m != nil { 71 | return m.D 72 | } 73 | return "" 74 | } 75 | 76 | func (m *Payload) GetE() bool { 77 | if m != nil { 78 | return m.E 79 | } 80 | return false 81 | } 82 | 83 | func (m *Payload) GetF() int64 { 84 | if m != nil { 85 | return m.F 86 | } 87 | return 0 88 | } 89 | 90 | func (m *Payload) GetG() string { 91 | if m != nil { 92 | return m.G 93 | } 94 | return "" 95 | } 96 | 97 | func init() { 98 | proto.RegisterType((*Payload)(nil), "main.Payload") 99 | } 100 | 101 | // Reference imports to suppress errors if they are not otherwise used. 102 | var _ context.Context 103 | var _ grpc.ClientConn 104 | 105 | // This is a compile-time assertion to ensure that this generated file 106 | // is compatible with the grpc package it is being compiled against. 107 | const _ = grpc.SupportPackageIsVersion4 108 | 109 | // Client API for Hello service 110 | 111 | type HelloClient interface { 112 | SayHi(ctx context.Context, in *Payload, opts ...grpc.CallOption) (*Payload, error) 113 | } 114 | 115 | type helloClient struct { 116 | cc *grpc.ClientConn 117 | } 118 | 119 | func NewHelloClient(cc *grpc.ClientConn) HelloClient { 120 | return &helloClient{cc} 121 | } 122 | 123 | func (c *helloClient) SayHi(ctx context.Context, in *Payload, opts ...grpc.CallOption) (*Payload, error) { 124 | out := new(Payload) 125 | err := grpc.Invoke(ctx, "/main.Hello/SayHi", in, out, c.cc, opts...) 126 | if err != nil { 127 | return nil, err 128 | } 129 | return out, nil 130 | } 131 | 132 | // Server API for Hello service 133 | 134 | type HelloServer interface { 135 | SayHi(context.Context, *Payload) (*Payload, error) 136 | } 137 | 138 | func RegisterHelloServer(s *grpc.Server, srv HelloServer) { 139 | s.RegisterService(&_Hello_serviceDesc, srv) 140 | } 141 | 142 | func _Hello_SayHi_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 143 | in := new(Payload) 144 | if err := dec(in); err != nil { 145 | return nil, err 146 | } 147 | if interceptor == nil { 148 | return srv.(HelloServer).SayHi(ctx, in) 149 | } 150 | info := &grpc.UnaryServerInfo{ 151 | Server: srv, 152 | FullMethod: "/main.Hello/SayHi", 153 | } 154 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 155 | return srv.(HelloServer).SayHi(ctx, req.(*Payload)) 156 | } 157 | return interceptor(ctx, in, info, handler) 158 | } 159 | 160 | var _Hello_serviceDesc = grpc.ServiceDesc{ 161 | ServiceName: "main.Hello", 162 | HandlerType: (*HelloServer)(nil), 163 | Methods: []grpc.MethodDesc{ 164 | { 165 | MethodName: "SayHi", 166 | Handler: _Hello_SayHi_Handler, 167 | }, 168 | }, 169 | Streams: []grpc.StreamDesc{}, 170 | Metadata: "common.proto", 171 | } 172 | 173 | func init() { proto.RegisterFile("common.proto", fileDescriptorCommon) } 174 | 175 | var fileDescriptorCommon = []byte{ 176 | // 162 bytes of a gzipped FileDescriptorProto 177 | 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x49, 0xce, 0xcf, 0xcd, 178 | 0xcd, 0xcf, 0xd3, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0xc9, 0x4d, 0xcc, 0xcc, 0x53, 0xca, 179 | 0xe6, 0x62, 0x0f, 0x48, 0xac, 0xcc, 0xc9, 0x4f, 0x4c, 0x11, 0xe2, 0xe1, 0x62, 0x74, 0x94, 0x60, 180 | 0x54, 0x60, 0xd4, 0xe0, 0x0c, 0x62, 0x74, 0x04, 0xf1, 0x9c, 0x24, 0x98, 0x20, 0x3c, 0x27, 0x10, 181 | 0xcf, 0x59, 0x82, 0x59, 0x81, 0x51, 0x83, 0x35, 0x88, 0xd1, 0x19, 0xc4, 0x73, 0x91, 0x60, 0x81, 182 | 0xc8, 0xb9, 0x80, 0x78, 0xae, 0x12, 0xac, 0x0a, 0x8c, 0x1a, 0x1c, 0x41, 0x8c, 0xae, 0x20, 0x9e, 183 | 0x9b, 0x04, 0x9b, 0x02, 0xa3, 0x06, 0x73, 0x10, 0xa3, 0x1b, 0x88, 0xe7, 0x2e, 0xc1, 0x0e, 0x51, 184 | 0xe9, 0x6e, 0xa4, 0xc7, 0xc5, 0xea, 0x91, 0x9a, 0x93, 0x93, 0x2f, 0xa4, 0xca, 0xc5, 0x1a, 0x9c, 185 | 0x58, 0xe9, 0x91, 0x29, 0xc4, 0xab, 0x07, 0x72, 0x85, 0x1e, 0xd4, 0x09, 0x52, 0xa8, 0xdc, 0x24, 186 | 0x36, 0xb0, 0x4b, 0x8d, 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0x8a, 0xda, 0x25, 0x2c, 0xb9, 0x00, 187 | 0x00, 0x00, 188 | } 189 | -------------------------------------------------------------------------------- /14/grpc/bench/single/grpc/protos/common.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-gogo. DO NOT EDIT. 2 | // source: common.proto 3 | 4 | /* 5 | Package main is a generated protocol buffer package. 6 | 7 | It is generated from these files: 8 | common.proto 9 | 10 | It has these top-level messages: 11 | Payload 12 | */ 13 | package main 14 | 15 | import proto "github.com/gogo/protobuf/proto" 16 | import fmt "fmt" 17 | import math "math" 18 | 19 | import context "golang.org/x/net/context" 20 | import grpc "google.golang.org/grpc" 21 | 22 | // Reference imports to suppress errors if they are not otherwise used. 23 | var _ = proto.Marshal 24 | var _ = fmt.Errorf 25 | var _ = math.Inf 26 | 27 | // This is a compile-time assertion to ensure that this generated file 28 | // is compatible with the proto package it is being compiled against. 29 | // A compilation error at this line likely means your copy of the 30 | // proto package needs to be updated. 31 | const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package 32 | 33 | type Payload struct { 34 | A string `protobuf:"bytes,1,opt,name=A,proto3" json:"A,omitempty"` 35 | B string `protobuf:"bytes,2,opt,name=B,proto3" json:"B,omitempty"` 36 | C int32 `protobuf:"varint,3,opt,name=C,proto3" json:"C,omitempty"` 37 | D string `protobuf:"bytes,4,opt,name=D,proto3" json:"D,omitempty"` 38 | E bool `protobuf:"varint,5,opt,name=E,proto3" json:"E,omitempty"` 39 | F int64 `protobuf:"varint,6,opt,name=F,proto3" json:"F,omitempty"` 40 | G string `protobuf:"bytes,7,opt,name=G,proto3" json:"G,omitempty"` 41 | } 42 | 43 | func (m *Payload) Reset() { *m = Payload{} } 44 | func (m *Payload) String() string { return proto.CompactTextString(m) } 45 | func (*Payload) ProtoMessage() {} 46 | func (*Payload) Descriptor() ([]byte, []int) { return fileDescriptorCommon, []int{0} } 47 | 48 | func (m *Payload) GetA() string { 49 | if m != nil { 50 | return m.A 51 | } 52 | return "" 53 | } 54 | 55 | func (m *Payload) GetB() string { 56 | if m != nil { 57 | return m.B 58 | } 59 | return "" 60 | } 61 | 62 | func (m *Payload) GetC() int32 { 63 | if m != nil { 64 | return m.C 65 | } 66 | return 0 67 | } 68 | 69 | func (m *Payload) GetD() string { 70 | if m != nil { 71 | return m.D 72 | } 73 | return "" 74 | } 75 | 76 | func (m *Payload) GetE() bool { 77 | if m != nil { 78 | return m.E 79 | } 80 | return false 81 | } 82 | 83 | func (m *Payload) GetF() int64 { 84 | if m != nil { 85 | return m.F 86 | } 87 | return 0 88 | } 89 | 90 | func (m *Payload) GetG() string { 91 | if m != nil { 92 | return m.G 93 | } 94 | return "" 95 | } 96 | 97 | func init() { 98 | proto.RegisterType((*Payload)(nil), "main.Payload") 99 | } 100 | 101 | // Reference imports to suppress errors if they are not otherwise used. 102 | var _ context.Context 103 | var _ grpc.ClientConn 104 | 105 | // This is a compile-time assertion to ensure that this generated file 106 | // is compatible with the grpc package it is being compiled against. 107 | const _ = grpc.SupportPackageIsVersion4 108 | 109 | // Client API for Hello service 110 | 111 | type HelloClient interface { 112 | SayHi(ctx context.Context, in *Payload, opts ...grpc.CallOption) (*Payload, error) 113 | } 114 | 115 | type helloClient struct { 116 | cc *grpc.ClientConn 117 | } 118 | 119 | func NewHelloClient(cc *grpc.ClientConn) HelloClient { 120 | return &helloClient{cc} 121 | } 122 | 123 | func (c *helloClient) SayHi(ctx context.Context, in *Payload, opts ...grpc.CallOption) (*Payload, error) { 124 | out := new(Payload) 125 | err := grpc.Invoke(ctx, "/main.Hello/SayHi", in, out, c.cc, opts...) 126 | if err != nil { 127 | return nil, err 128 | } 129 | return out, nil 130 | } 131 | 132 | // Server API for Hello service 133 | 134 | type HelloServer interface { 135 | SayHi(context.Context, *Payload) (*Payload, error) 136 | } 137 | 138 | func RegisterHelloServer(s *grpc.Server, srv HelloServer) { 139 | s.RegisterService(&_Hello_serviceDesc, srv) 140 | } 141 | 142 | func _Hello_SayHi_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 143 | in := new(Payload) 144 | if err := dec(in); err != nil { 145 | return nil, err 146 | } 147 | if interceptor == nil { 148 | return srv.(HelloServer).SayHi(ctx, in) 149 | } 150 | info := &grpc.UnaryServerInfo{ 151 | Server: srv, 152 | FullMethod: "/main.Hello/SayHi", 153 | } 154 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 155 | return srv.(HelloServer).SayHi(ctx, req.(*Payload)) 156 | } 157 | return interceptor(ctx, in, info, handler) 158 | } 159 | 160 | var _Hello_serviceDesc = grpc.ServiceDesc{ 161 | ServiceName: "main.Hello", 162 | HandlerType: (*HelloServer)(nil), 163 | Methods: []grpc.MethodDesc{ 164 | { 165 | MethodName: "SayHi", 166 | Handler: _Hello_SayHi_Handler, 167 | }, 168 | }, 169 | Streams: []grpc.StreamDesc{}, 170 | Metadata: "common.proto", 171 | } 172 | 173 | func init() { proto.RegisterFile("common.proto", fileDescriptorCommon) } 174 | 175 | var fileDescriptorCommon = []byte{ 176 | // 162 bytes of a gzipped FileDescriptorProto 177 | 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x49, 0xce, 0xcf, 0xcd, 178 | 0xcd, 0xcf, 0xd3, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0xc9, 0x4d, 0xcc, 0xcc, 0x53, 0xca, 179 | 0xe6, 0x62, 0x0f, 0x48, 0xac, 0xcc, 0xc9, 0x4f, 0x4c, 0x11, 0xe2, 0xe1, 0x62, 0x74, 0x94, 0x60, 180 | 0x54, 0x60, 0xd4, 0xe0, 0x0c, 0x62, 0x74, 0x04, 0xf1, 0x9c, 0x24, 0x98, 0x20, 0x3c, 0x27, 0x10, 181 | 0xcf, 0x59, 0x82, 0x59, 0x81, 0x51, 0x83, 0x35, 0x88, 0xd1, 0x19, 0xc4, 0x73, 0x91, 0x60, 0x81, 182 | 0xc8, 0xb9, 0x80, 0x78, 0xae, 0x12, 0xac, 0x0a, 0x8c, 0x1a, 0x1c, 0x41, 0x8c, 0xae, 0x20, 0x9e, 183 | 0x9b, 0x04, 0x9b, 0x02, 0xa3, 0x06, 0x73, 0x10, 0xa3, 0x1b, 0x88, 0xe7, 0x2e, 0xc1, 0x0e, 0x51, 184 | 0xe9, 0x6e, 0xa4, 0xc7, 0xc5, 0xea, 0x91, 0x9a, 0x93, 0x93, 0x2f, 0xa4, 0xca, 0xc5, 0x1a, 0x9c, 185 | 0x58, 0xe9, 0x91, 0x29, 0xc4, 0xab, 0x07, 0x72, 0x85, 0x1e, 0xd4, 0x09, 0x52, 0xa8, 0xdc, 0x24, 186 | 0x36, 0xb0, 0x4b, 0x8d, 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0x8a, 0xda, 0x25, 0x2c, 0xb9, 0x00, 187 | 0x00, 0x00, 188 | } 189 | -------------------------------------------------------------------------------- /14/grpc/bench/single/grpc/protos/common.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package main; 4 | 5 | service Hello { 6 | rpc SayHi(Payload) returns (Payload); 7 | } 8 | 9 | message Payload { 10 | string A = 1; 11 | string B = 2; 12 | int32 C = 3; 13 | string D = 4; 14 | bool E = 5; 15 | int64 F = 6; 16 | string G = 7; 17 | } -------------------------------------------------------------------------------- /14/grpc/bench/single/grpc/protos/gen.sh: -------------------------------------------------------------------------------- 1 | 2 | #!/bin/bash 3 | my_dir=`dirname $0` 4 | 5 | protoc -I=$my_dir -I=$GOPATH/src -I=$GOPATH/src/github.com/gogo/protobuf/protobuf --gogo_out=plugins=grpc:$my_dir/ $my_dir/*.proto -------------------------------------------------------------------------------- /14/grpc/bench/single/grpc/server/app.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "net" 7 | 8 | grpc "google.golang.org/grpc" 9 | ) 10 | 11 | func main() { 12 | // try to listening to bind address 13 | listen, err := net.Listen("tcp", fmt.Sprintf(":%d", 7777)) 14 | if err != nil { 15 | return 16 | } 17 | s := grpc.NewServer() 18 | RegisterHelloServer(s, &helloServer{}) 19 | 20 | if e := s.Serve(listen); e != nil { 21 | panic(e) 22 | } 23 | } 24 | 25 | type helloServer struct{} 26 | 27 | func (c *helloServer) SayHi(ctx context.Context, req *Payload) (resp *Payload, err error) { 28 | return req, nil 29 | } 30 | -------------------------------------------------------------------------------- /14/grpc/bench/single/grpc/server/common.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-gogo. DO NOT EDIT. 2 | // source: common.proto 3 | 4 | /* 5 | Package main is a generated protocol buffer package. 6 | 7 | It is generated from these files: 8 | common.proto 9 | 10 | It has these top-level messages: 11 | Payload 12 | */ 13 | package main 14 | 15 | import proto "github.com/gogo/protobuf/proto" 16 | import fmt "fmt" 17 | import math "math" 18 | 19 | import context "golang.org/x/net/context" 20 | import grpc "google.golang.org/grpc" 21 | 22 | // Reference imports to suppress errors if they are not otherwise used. 23 | var _ = proto.Marshal 24 | var _ = fmt.Errorf 25 | var _ = math.Inf 26 | 27 | // This is a compile-time assertion to ensure that this generated file 28 | // is compatible with the proto package it is being compiled against. 29 | // A compilation error at this line likely means your copy of the 30 | // proto package needs to be updated. 31 | const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package 32 | 33 | type Payload struct { 34 | A string `protobuf:"bytes,1,opt,name=A,proto3" json:"A,omitempty"` 35 | B string `protobuf:"bytes,2,opt,name=B,proto3" json:"B,omitempty"` 36 | C int32 `protobuf:"varint,3,opt,name=C,proto3" json:"C,omitempty"` 37 | D string `protobuf:"bytes,4,opt,name=D,proto3" json:"D,omitempty"` 38 | E bool `protobuf:"varint,5,opt,name=E,proto3" json:"E,omitempty"` 39 | F int64 `protobuf:"varint,6,opt,name=F,proto3" json:"F,omitempty"` 40 | G string `protobuf:"bytes,7,opt,name=G,proto3" json:"G,omitempty"` 41 | } 42 | 43 | func (m *Payload) Reset() { *m = Payload{} } 44 | func (m *Payload) String() string { return proto.CompactTextString(m) } 45 | func (*Payload) ProtoMessage() {} 46 | func (*Payload) Descriptor() ([]byte, []int) { return fileDescriptorCommon, []int{0} } 47 | 48 | func (m *Payload) GetA() string { 49 | if m != nil { 50 | return m.A 51 | } 52 | return "" 53 | } 54 | 55 | func (m *Payload) GetB() string { 56 | if m != nil { 57 | return m.B 58 | } 59 | return "" 60 | } 61 | 62 | func (m *Payload) GetC() int32 { 63 | if m != nil { 64 | return m.C 65 | } 66 | return 0 67 | } 68 | 69 | func (m *Payload) GetD() string { 70 | if m != nil { 71 | return m.D 72 | } 73 | return "" 74 | } 75 | 76 | func (m *Payload) GetE() bool { 77 | if m != nil { 78 | return m.E 79 | } 80 | return false 81 | } 82 | 83 | func (m *Payload) GetF() int64 { 84 | if m != nil { 85 | return m.F 86 | } 87 | return 0 88 | } 89 | 90 | func (m *Payload) GetG() string { 91 | if m != nil { 92 | return m.G 93 | } 94 | return "" 95 | } 96 | 97 | func init() { 98 | proto.RegisterType((*Payload)(nil), "main.Payload") 99 | } 100 | 101 | // Reference imports to suppress errors if they are not otherwise used. 102 | var _ context.Context 103 | var _ grpc.ClientConn 104 | 105 | // This is a compile-time assertion to ensure that this generated file 106 | // is compatible with the grpc package it is being compiled against. 107 | const _ = grpc.SupportPackageIsVersion4 108 | 109 | // Client API for Hello service 110 | 111 | type HelloClient interface { 112 | SayHi(ctx context.Context, in *Payload, opts ...grpc.CallOption) (*Payload, error) 113 | } 114 | 115 | type helloClient struct { 116 | cc *grpc.ClientConn 117 | } 118 | 119 | func NewHelloClient(cc *grpc.ClientConn) HelloClient { 120 | return &helloClient{cc} 121 | } 122 | 123 | func (c *helloClient) SayHi(ctx context.Context, in *Payload, opts ...grpc.CallOption) (*Payload, error) { 124 | out := new(Payload) 125 | err := grpc.Invoke(ctx, "/main.Hello/SayHi", in, out, c.cc, opts...) 126 | if err != nil { 127 | return nil, err 128 | } 129 | return out, nil 130 | } 131 | 132 | // Server API for Hello service 133 | 134 | type HelloServer interface { 135 | SayHi(context.Context, *Payload) (*Payload, error) 136 | } 137 | 138 | func RegisterHelloServer(s *grpc.Server, srv HelloServer) { 139 | s.RegisterService(&_Hello_serviceDesc, srv) 140 | } 141 | 142 | func _Hello_SayHi_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 143 | in := new(Payload) 144 | if err := dec(in); err != nil { 145 | return nil, err 146 | } 147 | if interceptor == nil { 148 | return srv.(HelloServer).SayHi(ctx, in) 149 | } 150 | info := &grpc.UnaryServerInfo{ 151 | Server: srv, 152 | FullMethod: "/main.Hello/SayHi", 153 | } 154 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 155 | return srv.(HelloServer).SayHi(ctx, req.(*Payload)) 156 | } 157 | return interceptor(ctx, in, info, handler) 158 | } 159 | 160 | var _Hello_serviceDesc = grpc.ServiceDesc{ 161 | ServiceName: "main.Hello", 162 | HandlerType: (*HelloServer)(nil), 163 | Methods: []grpc.MethodDesc{ 164 | { 165 | MethodName: "SayHi", 166 | Handler: _Hello_SayHi_Handler, 167 | }, 168 | }, 169 | Streams: []grpc.StreamDesc{}, 170 | Metadata: "common.proto", 171 | } 172 | 173 | func init() { proto.RegisterFile("common.proto", fileDescriptorCommon) } 174 | 175 | var fileDescriptorCommon = []byte{ 176 | // 162 bytes of a gzipped FileDescriptorProto 177 | 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x49, 0xce, 0xcf, 0xcd, 178 | 0xcd, 0xcf, 0xd3, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0xc9, 0x4d, 0xcc, 0xcc, 0x53, 0xca, 179 | 0xe6, 0x62, 0x0f, 0x48, 0xac, 0xcc, 0xc9, 0x4f, 0x4c, 0x11, 0xe2, 0xe1, 0x62, 0x74, 0x94, 0x60, 180 | 0x54, 0x60, 0xd4, 0xe0, 0x0c, 0x62, 0x74, 0x04, 0xf1, 0x9c, 0x24, 0x98, 0x20, 0x3c, 0x27, 0x10, 181 | 0xcf, 0x59, 0x82, 0x59, 0x81, 0x51, 0x83, 0x35, 0x88, 0xd1, 0x19, 0xc4, 0x73, 0x91, 0x60, 0x81, 182 | 0xc8, 0xb9, 0x80, 0x78, 0xae, 0x12, 0xac, 0x0a, 0x8c, 0x1a, 0x1c, 0x41, 0x8c, 0xae, 0x20, 0x9e, 183 | 0x9b, 0x04, 0x9b, 0x02, 0xa3, 0x06, 0x73, 0x10, 0xa3, 0x1b, 0x88, 0xe7, 0x2e, 0xc1, 0x0e, 0x51, 184 | 0xe9, 0x6e, 0xa4, 0xc7, 0xc5, 0xea, 0x91, 0x9a, 0x93, 0x93, 0x2f, 0xa4, 0xca, 0xc5, 0x1a, 0x9c, 185 | 0x58, 0xe9, 0x91, 0x29, 0xc4, 0xab, 0x07, 0x72, 0x85, 0x1e, 0xd4, 0x09, 0x52, 0xa8, 0xdc, 0x24, 186 | 0x36, 0xb0, 0x4b, 0x8d, 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0x8a, 0xda, 0x25, 0x2c, 0xb9, 0x00, 187 | 0x00, 0x00, 188 | } 189 | -------------------------------------------------------------------------------- /14/grpc/bench/single/grpc/server/vendor.conf: -------------------------------------------------------------------------------- 1 | # package 2 | github.com/linxGnu/meetup/14/grpc/bench/single/protobuf/server 3 | 4 | # import 5 | github.com/gogo/protobuf v1.0.0-14-g1ef32a8b 6 | github.com/golang/protobuf v1.1.0 7 | golang.org/x/net 640f462 8 | golang.org/x/text v0.3.0-47-g7922cc4 9 | google.golang.org/genproto 86e600f 10 | google.golang.org/grpc v1.8.1-161-ge944391 11 | -------------------------------------------------------------------------------- /14/grpc/bench/single/json/client/app.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "encoding/json" 6 | "fmt" 7 | "net/http" 8 | "sync" 9 | "sync/atomic" 10 | "time" 11 | ) 12 | 13 | var numWorker = 50 14 | var numRequest = 1000000 15 | var successCounter uint64 16 | 17 | var tr = &http.Transport{ 18 | MaxIdleConnsPerHost: 200, 19 | } 20 | var httpClient = http.Client{Transport: tr} 21 | 22 | type payload struct { 23 | A string `json:"a"` 24 | B string `json:"b"` 25 | C int `json:"c"` 26 | D string `json:"d"` 27 | E bool `json:"e"` 28 | F int64 `json:"f"` 29 | G string `json:"g"` 30 | } 31 | 32 | var p = &payload{ 33 | A: "12345678901234567890", 34 | B: "abcdefghijklmnopqus", 35 | C: 43545, 36 | D: "asgkasjeglkajsgjalsjdglaskdjglads", 37 | E: true, 38 | F: -135465748, 39 | G: "gejoiwbbbdfasaaaaaaaaaaaaaaaaa", 40 | } 41 | 42 | func main() { 43 | ch := make(chan struct{}, numWorker) 44 | 45 | // worker 46 | var wg sync.WaitGroup 47 | for i := 0; i < numWorker; i++ { 48 | wg.Add(1) 49 | go func() { 50 | for range ch { 51 | doTask() 52 | } 53 | wg.Done() 54 | }() 55 | } 56 | 57 | start := time.Now() 58 | for i := 0; i < numRequest; i++ { 59 | ch <- struct{}{} 60 | } 61 | close(ch) 62 | wg.Wait() 63 | end := time.Now() 64 | 65 | fmt.Println(end.Sub(start).Seconds(), fmt.Sprintf("%d / %d", successCounter, numRequest)) 66 | } 67 | 68 | func doTask() { 69 | b := new(bytes.Buffer) 70 | if err := json.NewEncoder(b).Encode(p); err != nil { 71 | return 72 | } 73 | 74 | resp, err := httpClient.Post("http://127.0.0.1:7777/hello", "application/json; charset=utf-8", b) 75 | if err != nil { 76 | return 77 | } 78 | 79 | var tmp payload 80 | if err = json.NewDecoder(resp.Body).Decode(&tmp); err != nil { 81 | return 82 | } 83 | 84 | atomic.AddUint64(&successCounter, 1) 85 | } 86 | -------------------------------------------------------------------------------- /14/grpc/bench/single/json/server/app.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "net/http" 7 | 8 | "github.com/gorilla/mux" 9 | ) 10 | 11 | type payload struct { 12 | A string `json:"a"` 13 | B string `json:"b"` 14 | C int `json:"c"` 15 | D string `json:"d"` 16 | E bool `json:"e"` 17 | F int64 `json:"f"` 18 | G string `json:"g"` 19 | } 20 | 21 | func main() { 22 | router := mux.NewRouter().StrictSlash(true) 23 | 24 | router.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) { 25 | var data payload 26 | if r.Body == nil { 27 | http.Error(w, "Please send a request body", 400) 28 | return 29 | } 30 | if err := json.NewDecoder(r.Body).Decode(&data); err != nil { 31 | fmt.Println(err) 32 | http.Error(w, err.Error(), 400) 33 | return 34 | } 35 | 36 | pl, err := json.Marshal(data) 37 | if err != nil { 38 | fmt.Println(err) 39 | http.Error(w, err.Error(), 400) 40 | return 41 | } 42 | 43 | w.Header().Set("Content-Type", "application/json") 44 | w.Write(pl) 45 | }) 46 | 47 | http.ListenAndServe(":7777", router) 48 | } 49 | -------------------------------------------------------------------------------- /14/grpc/bench/single/json/server/vendor.conf: -------------------------------------------------------------------------------- 1 | # package 2 | github.com/linxGnu/meetup/14/grpc/bench/single/json/server 3 | 4 | # import 5 | github.com/gorilla/context v1.1-7-g08b5f42 6 | github.com/gorilla/mux v1.6.1-16-gded0c29 7 | -------------------------------------------------------------------------------- /14/grpc/bench/single/protobuf/client/app.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "io/ioutil" 7 | "net/http" 8 | "sync" 9 | "sync/atomic" 10 | "time" 11 | 12 | "github.com/golang/protobuf/proto" 13 | ) 14 | 15 | var numWorker = 50 16 | var numRequest = 1000000 17 | var successCounter uint64 18 | 19 | var tr = &http.Transport{ 20 | MaxIdleConnsPerHost: 200, 21 | } 22 | var httpClient = http.Client{Transport: tr} 23 | 24 | var p = &Payload{ 25 | A: "12345678901234567890", 26 | B: "abcdefghijklmnopqus", 27 | C: 43545, 28 | D: "asgkasjeglkajsgjalsjdglaskdjglads", 29 | E: true, 30 | F: -135465748, 31 | G: "gejoiwbbbdfasaaaaaaaaaaaaaaaaa", 32 | } 33 | 34 | func main() { 35 | ch := make(chan struct{}, numWorker) 36 | 37 | // worker 38 | var wg sync.WaitGroup 39 | for i := 0; i < numWorker; i++ { 40 | wg.Add(1) 41 | go func() { 42 | for range ch { 43 | doTask() 44 | } 45 | wg.Done() 46 | }() 47 | } 48 | 49 | start := time.Now() 50 | for i := 0; i < numRequest; i++ { 51 | ch <- struct{}{} 52 | } 53 | close(ch) 54 | wg.Wait() 55 | end := time.Now() 56 | 57 | fmt.Println(end.Sub(start).Seconds(), fmt.Sprintf("%d / %d", successCounter, numRequest)) 58 | } 59 | 60 | func doTask() { 61 | pl, err := proto.Marshal(p) 62 | if err != nil { 63 | return 64 | } 65 | 66 | resp, err := httpClient.Post("http://127.0.0.1:7777/hello", "application/protobuf", bytes.NewReader(pl)) 67 | if err != nil { 68 | return 69 | } 70 | 71 | buf, err := ioutil.ReadAll(resp.Body) 72 | if err != nil { 73 | return 74 | } 75 | 76 | var tmp Payload 77 | if err = proto.Unmarshal(buf, &tmp); err != nil { 78 | return 79 | } 80 | 81 | atomic.AddUint64(&successCounter, 1) 82 | } 83 | -------------------------------------------------------------------------------- /14/grpc/bench/single/protobuf/client/common.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-gogo. DO NOT EDIT. 2 | // source: common.proto 3 | 4 | /* 5 | Package main is a generated protocol buffer package. 6 | 7 | It is generated from these files: 8 | common.proto 9 | 10 | It has these top-level messages: 11 | Payload 12 | */ 13 | package main 14 | 15 | import proto "github.com/gogo/protobuf/proto" 16 | import fmt "fmt" 17 | import math "math" 18 | 19 | // Reference imports to suppress errors if they are not otherwise used. 20 | var _ = proto.Marshal 21 | var _ = fmt.Errorf 22 | var _ = math.Inf 23 | 24 | // This is a compile-time assertion to ensure that this generated file 25 | // is compatible with the proto package it is being compiled against. 26 | // A compilation error at this line likely means your copy of the 27 | // proto package needs to be updated. 28 | const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package 29 | 30 | type Payload struct { 31 | A string `protobuf:"bytes,1,opt,name=A,proto3" json:"A,omitempty"` 32 | B string `protobuf:"bytes,2,opt,name=B,proto3" json:"B,omitempty"` 33 | C int32 `protobuf:"varint,3,opt,name=C,proto3" json:"C,omitempty"` 34 | D string `protobuf:"bytes,4,opt,name=D,proto3" json:"D,omitempty"` 35 | E bool `protobuf:"varint,5,opt,name=E,proto3" json:"E,omitempty"` 36 | F int64 `protobuf:"varint,6,opt,name=F,proto3" json:"F,omitempty"` 37 | G string `protobuf:"bytes,7,opt,name=G,proto3" json:"G,omitempty"` 38 | } 39 | 40 | func (m *Payload) Reset() { *m = Payload{} } 41 | func (m *Payload) String() string { return proto.CompactTextString(m) } 42 | func (*Payload) ProtoMessage() {} 43 | func (*Payload) Descriptor() ([]byte, []int) { return fileDescriptorCommon, []int{0} } 44 | 45 | func (m *Payload) GetA() string { 46 | if m != nil { 47 | return m.A 48 | } 49 | return "" 50 | } 51 | 52 | func (m *Payload) GetB() string { 53 | if m != nil { 54 | return m.B 55 | } 56 | return "" 57 | } 58 | 59 | func (m *Payload) GetC() int32 { 60 | if m != nil { 61 | return m.C 62 | } 63 | return 0 64 | } 65 | 66 | func (m *Payload) GetD() string { 67 | if m != nil { 68 | return m.D 69 | } 70 | return "" 71 | } 72 | 73 | func (m *Payload) GetE() bool { 74 | if m != nil { 75 | return m.E 76 | } 77 | return false 78 | } 79 | 80 | func (m *Payload) GetF() int64 { 81 | if m != nil { 82 | return m.F 83 | } 84 | return 0 85 | } 86 | 87 | func (m *Payload) GetG() string { 88 | if m != nil { 89 | return m.G 90 | } 91 | return "" 92 | } 93 | 94 | func init() { 95 | proto.RegisterType((*Payload)(nil), "main.Payload") 96 | } 97 | 98 | func init() { proto.RegisterFile("common.proto", fileDescriptorCommon) } 99 | 100 | var fileDescriptorCommon = []byte{ 101 | // 132 bytes of a gzipped FileDescriptorProto 102 | 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x49, 0xce, 0xcf, 0xcd, 103 | 0xcd, 0xcf, 0xd3, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0xc9, 0x4d, 0xcc, 0xcc, 0x53, 0xca, 104 | 0xe6, 0x62, 0x0f, 0x48, 0xac, 0xcc, 0xc9, 0x4f, 0x4c, 0x11, 0xe2, 0xe1, 0x62, 0x74, 0x94, 0x60, 105 | 0x54, 0x60, 0xd4, 0xe0, 0x0c, 0x62, 0x74, 0x04, 0xf1, 0x9c, 0x24, 0x98, 0x20, 0x3c, 0x27, 0x10, 106 | 0xcf, 0x59, 0x82, 0x59, 0x81, 0x51, 0x83, 0x35, 0x88, 0xd1, 0x19, 0xc4, 0x73, 0x91, 0x60, 0x81, 107 | 0xc8, 0xb9, 0x80, 0x78, 0xae, 0x12, 0xac, 0x0a, 0x8c, 0x1a, 0x1c, 0x41, 0x8c, 0xae, 0x20, 0x9e, 108 | 0x9b, 0x04, 0x9b, 0x02, 0xa3, 0x06, 0x73, 0x10, 0xa3, 0x1b, 0x88, 0xe7, 0x2e, 0xc1, 0x0e, 0x51, 109 | 0xe9, 0x9e, 0xc4, 0x06, 0xb6, 0xd9, 0x18, 0x10, 0x00, 0x00, 0xff, 0xff, 0xdd, 0x66, 0x6f, 0x2b, 110 | 0x89, 0x00, 0x00, 0x00, 111 | } 112 | -------------------------------------------------------------------------------- /14/grpc/bench/single/protobuf/client/vendor.conf: -------------------------------------------------------------------------------- 1 | # package 2 | github.com/linxGnu/meetup/14/grpc/bench/single/protobuf/client 3 | 4 | # import 5 | github.com/gogo/protobuf v1.0.0-14-g1ef32a8b 6 | github.com/golang/protobuf v1.1.0 7 | -------------------------------------------------------------------------------- /14/grpc/bench/single/protobuf/protos/common.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-gogo. DO NOT EDIT. 2 | // source: common.proto 3 | 4 | /* 5 | Package main is a generated protocol buffer package. 6 | 7 | It is generated from these files: 8 | common.proto 9 | 10 | It has these top-level messages: 11 | Payload 12 | */ 13 | package main 14 | 15 | import proto "github.com/gogo/protobuf/proto" 16 | import fmt "fmt" 17 | import math "math" 18 | 19 | // Reference imports to suppress errors if they are not otherwise used. 20 | var _ = proto.Marshal 21 | var _ = fmt.Errorf 22 | var _ = math.Inf 23 | 24 | // This is a compile-time assertion to ensure that this generated file 25 | // is compatible with the proto package it is being compiled against. 26 | // A compilation error at this line likely means your copy of the 27 | // proto package needs to be updated. 28 | const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package 29 | 30 | type Payload struct { 31 | A string `protobuf:"bytes,1,opt,name=A,proto3" json:"A,omitempty"` 32 | B string `protobuf:"bytes,2,opt,name=B,proto3" json:"B,omitempty"` 33 | C int32 `protobuf:"varint,3,opt,name=C,proto3" json:"C,omitempty"` 34 | D string `protobuf:"bytes,4,opt,name=D,proto3" json:"D,omitempty"` 35 | E bool `protobuf:"varint,5,opt,name=E,proto3" json:"E,omitempty"` 36 | F int64 `protobuf:"varint,6,opt,name=F,proto3" json:"F,omitempty"` 37 | G string `protobuf:"bytes,7,opt,name=G,proto3" json:"G,omitempty"` 38 | } 39 | 40 | func (m *Payload) Reset() { *m = Payload{} } 41 | func (m *Payload) String() string { return proto.CompactTextString(m) } 42 | func (*Payload) ProtoMessage() {} 43 | func (*Payload) Descriptor() ([]byte, []int) { return fileDescriptorCommon, []int{0} } 44 | 45 | func (m *Payload) GetA() string { 46 | if m != nil { 47 | return m.A 48 | } 49 | return "" 50 | } 51 | 52 | func (m *Payload) GetB() string { 53 | if m != nil { 54 | return m.B 55 | } 56 | return "" 57 | } 58 | 59 | func (m *Payload) GetC() int32 { 60 | if m != nil { 61 | return m.C 62 | } 63 | return 0 64 | } 65 | 66 | func (m *Payload) GetD() string { 67 | if m != nil { 68 | return m.D 69 | } 70 | return "" 71 | } 72 | 73 | func (m *Payload) GetE() bool { 74 | if m != nil { 75 | return m.E 76 | } 77 | return false 78 | } 79 | 80 | func (m *Payload) GetF() int64 { 81 | if m != nil { 82 | return m.F 83 | } 84 | return 0 85 | } 86 | 87 | func (m *Payload) GetG() string { 88 | if m != nil { 89 | return m.G 90 | } 91 | return "" 92 | } 93 | 94 | func init() { 95 | proto.RegisterType((*Payload)(nil), "main.Payload") 96 | } 97 | 98 | func init() { proto.RegisterFile("common.proto", fileDescriptorCommon) } 99 | 100 | var fileDescriptorCommon = []byte{ 101 | // 132 bytes of a gzipped FileDescriptorProto 102 | 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x49, 0xce, 0xcf, 0xcd, 103 | 0xcd, 0xcf, 0xd3, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0xc9, 0x4d, 0xcc, 0xcc, 0x53, 0xca, 104 | 0xe6, 0x62, 0x0f, 0x48, 0xac, 0xcc, 0xc9, 0x4f, 0x4c, 0x11, 0xe2, 0xe1, 0x62, 0x74, 0x94, 0x60, 105 | 0x54, 0x60, 0xd4, 0xe0, 0x0c, 0x62, 0x74, 0x04, 0xf1, 0x9c, 0x24, 0x98, 0x20, 0x3c, 0x27, 0x10, 106 | 0xcf, 0x59, 0x82, 0x59, 0x81, 0x51, 0x83, 0x35, 0x88, 0xd1, 0x19, 0xc4, 0x73, 0x91, 0x60, 0x81, 107 | 0xc8, 0xb9, 0x80, 0x78, 0xae, 0x12, 0xac, 0x0a, 0x8c, 0x1a, 0x1c, 0x41, 0x8c, 0xae, 0x20, 0x9e, 108 | 0x9b, 0x04, 0x9b, 0x02, 0xa3, 0x06, 0x73, 0x10, 0xa3, 0x1b, 0x88, 0xe7, 0x2e, 0xc1, 0x0e, 0x51, 109 | 0xe9, 0x9e, 0xc4, 0x06, 0xb6, 0xd9, 0x18, 0x10, 0x00, 0x00, 0xff, 0xff, 0xdd, 0x66, 0x6f, 0x2b, 110 | 0x89, 0x00, 0x00, 0x00, 111 | } 112 | -------------------------------------------------------------------------------- /14/grpc/bench/single/protobuf/protos/common.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package main; 4 | 5 | message Payload { 6 | string A = 1; 7 | string B = 2; 8 | int32 C = 3; 9 | string D = 4; 10 | bool E = 5; 11 | int64 F = 6; 12 | string G = 7; 13 | } -------------------------------------------------------------------------------- /14/grpc/bench/single/protobuf/protos/gen.sh: -------------------------------------------------------------------------------- 1 | 2 | #!/bin/bash 3 | my_dir=`dirname $0` 4 | 5 | protoc -I=$my_dir -I=$GOPATH/src -I=$GOPATH/src/github.com/gogo/protobuf/protobuf --gogo_out=$my_dir/ $my_dir/*.proto -------------------------------------------------------------------------------- /14/grpc/bench/single/protobuf/server/app.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io/ioutil" 6 | "net/http" 7 | 8 | "github.com/golang/protobuf/proto" 9 | "github.com/gorilla/mux" 10 | ) 11 | 12 | func main() { 13 | router := mux.NewRouter().StrictSlash(true) 14 | 15 | router.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) { 16 | if r.Body == nil { 17 | http.Error(w, "Please send a request body", 400) 18 | return 19 | } 20 | 21 | buf, err := ioutil.ReadAll(r.Body) 22 | if err != nil { 23 | fmt.Println(err) 24 | http.Error(w, err.Error(), 400) 25 | return 26 | } 27 | 28 | var data Payload 29 | if err := proto.Unmarshal(buf, &data); err != nil { 30 | fmt.Println(err) 31 | http.Error(w, err.Error(), 400) 32 | return 33 | } 34 | 35 | pl, err := proto.Marshal(&data) 36 | if err != nil { 37 | fmt.Println(err) 38 | http.Error(w, err.Error(), 400) 39 | return 40 | } 41 | 42 | w.Header().Set("Content-Type", "application/protobuf") 43 | w.Write(pl) 44 | }) 45 | 46 | http.ListenAndServe(":7777", router) 47 | } 48 | -------------------------------------------------------------------------------- /14/grpc/bench/single/protobuf/server/common.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-gogo. DO NOT EDIT. 2 | // source: common.proto 3 | 4 | /* 5 | Package main is a generated protocol buffer package. 6 | 7 | It is generated from these files: 8 | common.proto 9 | 10 | It has these top-level messages: 11 | Payload 12 | */ 13 | package main 14 | 15 | import proto "github.com/gogo/protobuf/proto" 16 | import fmt "fmt" 17 | import math "math" 18 | 19 | // Reference imports to suppress errors if they are not otherwise used. 20 | var _ = proto.Marshal 21 | var _ = fmt.Errorf 22 | var _ = math.Inf 23 | 24 | // This is a compile-time assertion to ensure that this generated file 25 | // is compatible with the proto package it is being compiled against. 26 | // A compilation error at this line likely means your copy of the 27 | // proto package needs to be updated. 28 | const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package 29 | 30 | type Payload struct { 31 | A string `protobuf:"bytes,1,opt,name=A,proto3" json:"A,omitempty"` 32 | B string `protobuf:"bytes,2,opt,name=B,proto3" json:"B,omitempty"` 33 | C int32 `protobuf:"varint,3,opt,name=C,proto3" json:"C,omitempty"` 34 | D string `protobuf:"bytes,4,opt,name=D,proto3" json:"D,omitempty"` 35 | E bool `protobuf:"varint,5,opt,name=E,proto3" json:"E,omitempty"` 36 | F int64 `protobuf:"varint,6,opt,name=F,proto3" json:"F,omitempty"` 37 | G string `protobuf:"bytes,7,opt,name=G,proto3" json:"G,omitempty"` 38 | } 39 | 40 | func (m *Payload) Reset() { *m = Payload{} } 41 | func (m *Payload) String() string { return proto.CompactTextString(m) } 42 | func (*Payload) ProtoMessage() {} 43 | func (*Payload) Descriptor() ([]byte, []int) { return fileDescriptorCommon, []int{0} } 44 | 45 | func (m *Payload) GetA() string { 46 | if m != nil { 47 | return m.A 48 | } 49 | return "" 50 | } 51 | 52 | func (m *Payload) GetB() string { 53 | if m != nil { 54 | return m.B 55 | } 56 | return "" 57 | } 58 | 59 | func (m *Payload) GetC() int32 { 60 | if m != nil { 61 | return m.C 62 | } 63 | return 0 64 | } 65 | 66 | func (m *Payload) GetD() string { 67 | if m != nil { 68 | return m.D 69 | } 70 | return "" 71 | } 72 | 73 | func (m *Payload) GetE() bool { 74 | if m != nil { 75 | return m.E 76 | } 77 | return false 78 | } 79 | 80 | func (m *Payload) GetF() int64 { 81 | if m != nil { 82 | return m.F 83 | } 84 | return 0 85 | } 86 | 87 | func (m *Payload) GetG() string { 88 | if m != nil { 89 | return m.G 90 | } 91 | return "" 92 | } 93 | 94 | func init() { 95 | proto.RegisterType((*Payload)(nil), "main.Payload") 96 | } 97 | 98 | func init() { proto.RegisterFile("common.proto", fileDescriptorCommon) } 99 | 100 | var fileDescriptorCommon = []byte{ 101 | // 132 bytes of a gzipped FileDescriptorProto 102 | 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x49, 0xce, 0xcf, 0xcd, 103 | 0xcd, 0xcf, 0xd3, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0xc9, 0x4d, 0xcc, 0xcc, 0x53, 0xca, 104 | 0xe6, 0x62, 0x0f, 0x48, 0xac, 0xcc, 0xc9, 0x4f, 0x4c, 0x11, 0xe2, 0xe1, 0x62, 0x74, 0x94, 0x60, 105 | 0x54, 0x60, 0xd4, 0xe0, 0x0c, 0x62, 0x74, 0x04, 0xf1, 0x9c, 0x24, 0x98, 0x20, 0x3c, 0x27, 0x10, 106 | 0xcf, 0x59, 0x82, 0x59, 0x81, 0x51, 0x83, 0x35, 0x88, 0xd1, 0x19, 0xc4, 0x73, 0x91, 0x60, 0x81, 107 | 0xc8, 0xb9, 0x80, 0x78, 0xae, 0x12, 0xac, 0x0a, 0x8c, 0x1a, 0x1c, 0x41, 0x8c, 0xae, 0x20, 0x9e, 108 | 0x9b, 0x04, 0x9b, 0x02, 0xa3, 0x06, 0x73, 0x10, 0xa3, 0x1b, 0x88, 0xe7, 0x2e, 0xc1, 0x0e, 0x51, 109 | 0xe9, 0x9e, 0xc4, 0x06, 0xb6, 0xd9, 0x18, 0x10, 0x00, 0x00, 0xff, 0xff, 0xdd, 0x66, 0x6f, 0x2b, 110 | 0x89, 0x00, 0x00, 0x00, 111 | } 112 | -------------------------------------------------------------------------------- /14/grpc/bench/single/protobuf/server/vendor.conf: -------------------------------------------------------------------------------- 1 | # package 2 | github.com/linxGnu/meetup/14/grpc/bench/single/protobuf/server 3 | 4 | # import 5 | github.com/golang/protobuf v1.1.0 6 | github.com/gorilla/context v1.1-7-g08b5f42 7 | github.com/gorilla/mux v1.6.1-16-gded0c29 8 | -------------------------------------------------------------------------------- /14/grpc/images/b1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/14/grpc/images/b1.png -------------------------------------------------------------------------------- /14/grpc/images/b2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/14/grpc/images/b2.png -------------------------------------------------------------------------------- /14/grpc/images/b3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/14/grpc/images/b3.png -------------------------------------------------------------------------------- /14/grpc/images/browndrink.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/14/grpc/images/browndrink.jpg -------------------------------------------------------------------------------- /14/grpc/images/clientlb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/14/grpc/images/clientlb.png -------------------------------------------------------------------------------- /14/grpc/images/clientside.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/14/grpc/images/clientside.png -------------------------------------------------------------------------------- /14/grpc/images/grpclogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/14/grpc/images/grpclogo.png -------------------------------------------------------------------------------- /14/grpc/images/ipc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/14/grpc/images/ipc.png -------------------------------------------------------------------------------- /14/grpc/images/lbproxy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/14/grpc/images/lbproxy.png -------------------------------------------------------------------------------- /14/grpc/images/ms.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/14/grpc/images/ms.png -------------------------------------------------------------------------------- /14/grpc/images/pubsub.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/14/grpc/images/pubsub.png -------------------------------------------------------------------------------- /14/grpc/images/rest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/14/grpc/images/rest.png -------------------------------------------------------------------------------- /14/grpc/images/serverside.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/14/grpc/images/serverside.png -------------------------------------------------------------------------------- /14/grpc/images/srvdiscovery1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/14/grpc/images/srvdiscovery1.png -------------------------------------------------------------------------------- /14/grpc/images/team.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/14/grpc/images/team.png -------------------------------------------------------------------------------- /14/grpc/images/think.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/14/grpc/images/think.jpg -------------------------------------------------------------------------------- /14/grpc/images/usecase.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/14/grpc/images/usecase.png -------------------------------------------------------------------------------- /14/grpc/runslide.sh: -------------------------------------------------------------------------------- 1 | present -play -http localhost:10000 2 | -------------------------------------------------------------------------------- /15/_race/README.MD: -------------------------------------------------------------------------------- 1 | Install Go present and run: 2 | 3 | ``` 4 | present -play -orighost localhost 5 | ``` 6 | -------------------------------------------------------------------------------- /15/_race/code/example1.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | var count = 0 9 | 10 | func counter() { 11 | for j := 0; j < 100; j++ { 12 | count++ 13 | } 14 | } 15 | 16 | func main() { 17 | for i := 0; i < 100; i++ { 18 | go counter() 19 | } 20 | time.Sleep(200 * time.Millisecond) 21 | fmt.Println(count) 22 | } 23 | -------------------------------------------------------------------------------- /15/_race/code/example2.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func main() { 9 | var message string 10 | 11 | go func() { 12 | message = "Hello, Go" 13 | }() 14 | time.Sleep(4 * time.Microsecond) 15 | fmt.Println(message) 16 | } 17 | -------------------------------------------------------------------------------- /15/_race/code/example3.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | var count = 0 9 | 10 | func incrementJustOnce() { 11 | if count == 0 { 12 | time.Sleep(1 * time.Nanosecond) 13 | count++ 14 | } 15 | } 16 | 17 | func main() { 18 | for i := 0; i < 10; i++ { 19 | go incrementJustOnce() 20 | } 21 | time.Sleep(10 * time.Millisecond) 22 | fmt.Println(count) 23 | } 24 | -------------------------------------------------------------------------------- /15/_race/images/race1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/15/_race/images/race1.png -------------------------------------------------------------------------------- /15/_race/images/race2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/15/_race/images/race2.jpg -------------------------------------------------------------------------------- /15/_race/misc/example2.result.txt: -------------------------------------------------------------------------------- 1 | ================== 2 | WARNING: DATA RACE 3 | Write at 0x00c4200861b0 by goroutine 6: 4 | main.main.func1() 5 | /Users/duythinht/workspace/meetup/example2.go:9 +0x3b 6 | 7 | Previous read at 0x00c4200861b0 by main goroutine: 8 | main.main() 9 | /Users/duythinht/workspace/meetup/example2.go:12 +0xa4 10 | 11 | Goroutine 6 (running) created at: 12 | main.main() 13 | /Users/duythinht/workspace/meetup/example2.go:8 +0x93 14 | ================== 15 | Found 1 data race(s) 16 | exit status 66 17 | -------------------------------------------------------------------------------- /15/_race/misc/race_detector.sh: -------------------------------------------------------------------------------- 1 | $ go test -race mypkg // to test the package 2 | $ go run -race mysrc.go // to run the source file 3 | $ go build -race mycmd // to build the command 4 | $ go install -race mypkg // to install the package 5 | -------------------------------------------------------------------------------- /15/_race/race.slide: -------------------------------------------------------------------------------- 1 | Data races in Go 2 | 3 | 7 Aug 2018 4 | 5 | Thinh Tran 6 | Software engineer 7 | duythinht@gmail.com 8 | http://@duythinht 9 | 10 | * What is value of count? 11 | .play ./code/example1.go 12 | 13 | * Data races 14 | 15 | When two+ goroutines concurrently access a shared memory location, at least one access is write. 16 | 17 | .play ./code/example2.go 18 | 19 | * What happended? 20 | .image ./images/race1.png 21 | 22 | * Concurrency 23 | .play ./code/example3.go 24 | 25 | * Concurrency 26 | .image ./images/race2.jpg 27 | 28 | * Race detector 29 | 30 | .code ./misc/race_detector.sh 31 | .code ./misc/example2.result.txt 32 | 33 | * Race detector 34 | - Go v1.1 (2013) 35 | - Based on C/C++ ThreadSanitizer 36 | - Integrated with go tool chain 37 | - As August 2015: 38 | ~ 1200 races in Google's codebase 39 | ~ 100 in Go stdlib 40 | 100+ in chromium 41 | ... 42 | - Program slowdown 5-15x 43 | - Memory usage 5-10x 44 | 45 | * How to prevent data races? 46 | 47 | Serialize memory access 48 | 49 | - Lock/Unlock using `sync.Mutex` or `sync.RWMutex` 50 | - Lazy initialization using `sync.Once` 51 | - Using `sync.atomic` for synchronization primitives 52 | - Synchronization between goroutines using go channel 53 | 54 | * References 55 | 56 | .link https://blog.golang.org/race-detector Go blog, race detector 57 | .link https://golang.org/doc/articles/race_detector.html Data race detector 58 | .link https://golang.org/ref/mem#tmp_10 The Go memory model 59 | .link https://github.com/google/sanitizers/wiki/ThreadSanitizerAlgorithm ThreadSanitizerAlgorithm 60 | .link https://www.infoq.com/presentations/go-race-detector Looking inside a Race detector 61 | -------------------------------------------------------------------------------- /15/code_generator/Code generator.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/15/code_generator/Code generator.pdf -------------------------------------------------------------------------------- /15/code_generator/examples/ast/example.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func A() (int, error) { 4 | err := B() 5 | 6 | return 10, nil 7 | } 8 | 9 | func B() error { 10 | err := C() 11 | 12 | return nil 13 | } 14 | 15 | func C() error { 16 | return nil 17 | } 18 | -------------------------------------------------------------------------------- /15/code_generator/examples/ast/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "go/ast" 7 | "go/parser" 8 | "go/printer" 9 | "go/token" 10 | "io/ioutil" 11 | "os" 12 | 13 | "github.com/Sirupsen/logrus" 14 | ) 15 | 16 | var ( 17 | fset = token.NewFileSet() 18 | ) 19 | 20 | func main() { 21 | 22 | f, _ := parser.ParseFile(fset, "example.go", nil, 0) 23 | 24 | for _, node2 := range f.Decls { 25 | switch node1 := node2.(type) { 26 | case *ast.FuncDecl: 27 | ast.Inspect(node1, func(node ast.Node) bool { 28 | switch node := node.(type) { 29 | case *ast.BlockStmt: 30 | writeBlock(node, node1) 31 | } 32 | return true 33 | }) 34 | } 35 | 36 | } 37 | 38 | writeToFile("example.go", f) 39 | } 40 | 41 | func writeBlock(node *ast.BlockStmt, node1 *ast.FuncDecl) { 42 | for i, v := range node.List { 43 | switch v := v.(type) { 44 | case *ast.AssignStmt: 45 | writeAssign(v, node, node1, i) 46 | } 47 | } 48 | } 49 | 50 | func writeAssign(v *ast.AssignStmt, node *ast.BlockStmt, node1 *ast.FuncDecl, i int) { 51 | for _, k := range v.Lhs { 52 | if l, ok := k.(*ast.Ident); ok { 53 | if l.Name == "err" { 54 | var returnRet []ast.Expr 55 | 56 | for _, r := range node1.Type.Results.List { 57 | switch r := r.Type.(type) { 58 | case *ast.Ident: 59 | switch r.Name { 60 | case "int": 61 | returnRet = append(returnRet, ast.NewIdent("0")) 62 | case "error": 63 | returnRet = append(returnRet, ast.NewIdent("err")) 64 | } 65 | 66 | } 67 | } 68 | body := &ast.BlockStmt{ 69 | Lbrace: l.Pos() + 1, 70 | List: []ast.Stmt{ 71 | &ast.ReturnStmt{ 72 | Return: l.Pos() + 2, 73 | Results: returnRet, 74 | }, 75 | }, 76 | Rbrace: l.Pos() + 3, 77 | } 78 | 79 | ifs := &ast.IfStmt{ 80 | Cond: ast.NewIdent("err != nil"), 81 | Body: body, 82 | } 83 | 84 | // allocate a new statement list big enough for our new statement 85 | j := i + 1 86 | list := make([]ast.Stmt, len(node.List)+1) 87 | copy(list, node.List[:j]) 88 | list[j] = ifs 89 | copy(list[j+1:], node.List[j:]) 90 | node.List = list 91 | 92 | } 93 | } 94 | } 95 | } 96 | 97 | func writeToFile(fname string, f *ast.File) { 98 | buf := &bytes.Buffer{} 99 | err := printer.Fprint(buf, fset, f) 100 | if err != nil { 101 | logrus.Fatal(err) 102 | } 103 | 104 | err = ioutil.WriteFile(fname, buf.Bytes(), os.ModePerm) 105 | if err != nil { 106 | logrus.Fatal("Unable to write to file", err) 107 | } 108 | 109 | /* out, err := exec.Command("gofmt", "-w", fname).Output() */ 110 | // if err != nil { 111 | // logrus.Fatal("Unable to run gofmt", fname, err, string(out)) 112 | /* } */ 113 | 114 | fmt.Println("–– Write to file", fname) 115 | } 116 | -------------------------------------------------------------------------------- /15/code_generator/examples/stringer/enum/enum.go: -------------------------------------------------------------------------------- 1 | package enum 2 | 3 | //go:generate stringer -type=ChangeType -output=gen.go 4 | type ChangeType int 5 | 6 | const ( 7 | UpsertJSON ChangeType = iota + 1 8 | UpsertText 9 | Remove 10 | Rename 11 | ApplyJSONPatch 12 | ApplyTextPatch 13 | ) 14 | -------------------------------------------------------------------------------- /15/code_generator/examples/stringer/enum/gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by "stringer -type=ChangeType -output=gen.go"; DO NOT EDIT. 2 | 3 | package enum 4 | 5 | import "strconv" 6 | 7 | const _ChangeType_name = "UpsertJSONUpsertTextRemoveRenameApplyJSONPatchApplyTextPatch" 8 | 9 | var _ChangeType_index = [...]uint8{0, 10, 20, 26, 32, 46, 60} 10 | 11 | func (i ChangeType) String() string { 12 | i -= 1 13 | if i < 0 || i >= ChangeType(len(_ChangeType_index)-1) { 14 | return "ChangeType(" + strconv.FormatInt(int64(i+1), 10) + ")" 15 | } 16 | return _ChangeType_name[_ChangeType_index[i]:_ChangeType_index[i+1]] 17 | } 18 | -------------------------------------------------------------------------------- /15/code_generator/examples/stringer/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | import "./enum" 5 | 6 | func main() { 7 | var c enum.ChangeType = enum.Rename 8 | 9 | fmt.Println(c.String()) 10 | } 11 | -------------------------------------------------------------------------------- /17-VN-gophers-after-COVID/effectivego/README.md: -------------------------------------------------------------------------------- 1 | Install Go present and run: 2 | 3 | ``` 4 | present -play -orighost localhost 5 | ``` -------------------------------------------------------------------------------- /17-VN-gophers-after-COVID/effectivego/example/assertion/notok.go: -------------------------------------------------------------------------------- 1 | package example 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | var i interface{} = "hello" 7 | 8 | f = i.(float64) // run time panic: interface conversion: interface {} is string, not float64 9 | fmt.Println(f) 10 | } 11 | -------------------------------------------------------------------------------- /17-VN-gophers-after-COVID/effectivego/example/assertion/ok.go: -------------------------------------------------------------------------------- 1 | package example 2 | 3 | func main() { 4 | var i interface{} = "hello" 5 | 6 | f, ok = i.(float64) 7 | if !ok { 8 | // don't use f 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /17-VN-gophers-after-COVID/effectivego/example/conversion/notmatch.go: -------------------------------------------------------------------------------- 1 | package example 2 | 3 | func main() { 4 | var str string = "hello" 5 | 6 | integer := int(str) // complile error: cannot convert str (type string) to type int 7 | } 8 | -------------------------------------------------------------------------------- /17-VN-gophers-after-COVID/effectivego/example/function/addinvoice.go: -------------------------------------------------------------------------------- 1 | package example 2 | 3 | func main() { 4 | o, q, t, i, err := CreateOrder("product id", "customer id", "shipment id") 5 | if err != nil { 6 | panic(err) 7 | } 8 | } 9 | 10 | // Return Invoice to show the invoice info in dashboard 11 | func CreateOrder(productID, customerID, shipmentID string) (Order, Quote, Transaction, Invoice, error) { 12 | return Order{}, Quote{}, Transaction{}, Invoice{}, nil 13 | } 14 | -------------------------------------------------------------------------------- /17-VN-gophers-after-COVID/effectivego/example/function/addquote.go: -------------------------------------------------------------------------------- 1 | package example 2 | 3 | func main() { 4 | o, q, err := CreateOrder("product id", "customer id", "shipment id") 5 | if err != nil { 6 | panic(err) 7 | } 8 | } 9 | 10 | // Return Quote to show the quote info in dashboard 11 | func CreateOrder(productID, customerID, shipmentID string) (Order, Quote, error) { 12 | return Order{}, Quote{}, nil 13 | } 14 | -------------------------------------------------------------------------------- /17-VN-gophers-after-COVID/effectivego/example/function/addrequestion.go: -------------------------------------------------------------------------------- 1 | package example 2 | 3 | type Order struct { 4 | ID string 5 | } 6 | 7 | func processRequest() { 8 | // What is this true stand for, why i put true value in here???? 9 | o, err := CreateOrder("product id", "customer id", "shipment id", true) 10 | if err != nil { 11 | panic(err) 12 | } 13 | } 14 | 15 | func CreateOrder(productID, customerID, shipmentID string, isPromotion bool) (Order, error) { 16 | return Order{}, nil 17 | } 18 | -------------------------------------------------------------------------------- /17-VN-gophers-after-COVID/effectivego/example/function/addtransaction.go: -------------------------------------------------------------------------------- 1 | package example 2 | 3 | func main() { 4 | o, q, t, err := CreateOrder("product id", "customer id", "shipment id") 5 | if err != nil { 6 | panic(err) 7 | } 8 | } 9 | 10 | // Return Transaction to show the transaction info in dashboard 11 | func CreateOrder(productID, customerID, shipmentID string) (Order, Quote, Transaction, error) { 12 | return Order{}, Quote{}, Transaction{}, nil 13 | } 14 | -------------------------------------------------------------------------------- /17-VN-gophers-after-COVID/effectivego/example/function/bad.go: -------------------------------------------------------------------------------- 1 | package example 2 | 3 | func main() { 4 | o, err := CreateOrder("product id", "customer id", "shipment id") 5 | if err != nil { 6 | panic(err) 7 | } 8 | } 9 | 10 | func CreateOrder(pID string, cID string, sID string) (Order, error) { 11 | return Order{}, nil 12 | } 13 | -------------------------------------------------------------------------------- /17-VN-gophers-after-COVID/effectivego/example/function/better.go: -------------------------------------------------------------------------------- 1 | package example 2 | 3 | func main() { 4 | o, err := CreateOrder("product id", "customer id", "shipment id") 5 | if err != nil { 6 | panic(err) 7 | } 8 | } 9 | 10 | func CreateOrder(productID, customerID, shipmentID string) (Order, error) { 11 | return Order{}, nil 12 | } 13 | -------------------------------------------------------------------------------- /17-VN-gophers-after-COVID/effectivego/example/function/betterreturn.go: -------------------------------------------------------------------------------- 1 | package example 2 | 3 | func main() { 4 | order, err := CreateOrder("product id", "customer id", "shipment id") 5 | if err != nil { 6 | panic(err) 7 | } 8 | 9 | quote, err := CreateQuote(order.id) 10 | if err != nil { 11 | panic(err) 12 | } 13 | 14 | transaction, err := CreateTransaction(order.id) 15 | if err != nil { 16 | panic(err) 17 | } 18 | 19 | invoice, err := CreateInvoice(order.id) 20 | if err != nil { 21 | return nil, err 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /17-VN-gophers-after-COVID/effectivego/example/function/good.go: -------------------------------------------------------------------------------- 1 | package example 2 | 3 | func main() { 4 | o, err := CreateOrder("product id", "customer id", "shipment id") 5 | if err != nil { 6 | panic(err) 7 | } 8 | } 9 | 10 | func CreateOrder(productID string, customerID string, shipmentID string) (Order, error) { 11 | return Order{}, nil 12 | } 13 | -------------------------------------------------------------------------------- /17-VN-gophers-after-COVID/effectivego/example/function/passbool.go: -------------------------------------------------------------------------------- 1 | package example 2 | 3 | func processRequest() { 4 | o, err := CreateOrder("product id", "customer id", "shipment id", true) 5 | if err != nil { 6 | panic(err) 7 | } 8 | } 9 | 10 | func CreateOrder(productID, customerID, shipmentID string, isPromotion bool) (Order, error) { 11 | return Order{}, nil 12 | } 13 | -------------------------------------------------------------------------------- /17-VN-gophers-after-COVID/effectivego/example/function/returnfirst.go: -------------------------------------------------------------------------------- 1 | package example 2 | 3 | func processRequest(isPromotion bool) (Order, error) { 4 | if isPromotion { 5 | o, err := CreateOrderWithPromotionProduct() 6 | return o, err 7 | } 8 | 9 | o, err := CreateOrderWithNormalProduct() 10 | return o, err 11 | } 12 | -------------------------------------------------------------------------------- /17-VN-gophers-after-COVID/effectivego/example/function/switch.go: -------------------------------------------------------------------------------- 1 | package example 2 | 3 | func processRequest() (Order, error) { 4 | if isPromotion { 5 | order, err := CreateOrderWithPromotionProduct() 6 | return order, err 7 | } else { 8 | order, err := CreateOrderWithNormalProduct() 9 | return order, err 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /17-VN-gophers-after-COVID/effectivego/example/map/assertion.go: -------------------------------------------------------------------------------- 1 | package example 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | var _Check = func() map[string]int { 8 | return map[string]int{ 9 | "one": 1, 10 | "two": 2, 11 | "three": 3, 12 | "four": 4, 13 | } 14 | } 15 | 16 | func convertStringToInteger(input string) (int, error) { 17 | output, ok := _Check()[input] 18 | if !ok { 19 | return 0, fmt.Errorf("%s is not satisfy", input) 20 | } 21 | return output, nil 22 | } 23 | -------------------------------------------------------------------------------- /17-VN-gophers-after-COVID/effectivego/example/return/bad.go: -------------------------------------------------------------------------------- 1 | package example 2 | 3 | func handleSlice(input []string) { 4 | for i := range input { 5 | if input[i] != "" { 6 | // do some stuff 7 | } else { 8 | // handle zero value of element 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /17-VN-gophers-after-COVID/effectivego/example/return/good.go: -------------------------------------------------------------------------------- 1 | package example 2 | 3 | func handleSlice(input []string) { 4 | for i := range input { 5 | if input[i] == "" { 6 | // handle if needed 7 | continue 8 | } 9 | 10 | // do some stuff 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /17-VN-gophers-after-COVID/effectivego/image/baddocfunction.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/17-VN-gophers-after-COVID/effectivego/image/baddocfunction.png -------------------------------------------------------------------------------- /17-VN-gophers-after-COVID/effectivego/image/goodautocomplete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/17-VN-gophers-after-COVID/effectivego/image/goodautocomplete.png -------------------------------------------------------------------------------- /17-VN-gophers-after-COVID/effectivego/image/typingfunction.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/17-VN-gophers-after-COVID/effectivego/image/typingfunction.png -------------------------------------------------------------------------------- /17-VN-gophers-after-COVID/effectivego/present.slide: -------------------------------------------------------------------------------- 1 | Effective Go 2 | 3 | Vo Minh Khiem 4 | 28 June 2020 5 | vominhkhiem212@gmail.com 6 | 7 | * Agenda: 8 | - Readability 9 | - Type Conversion/Assertion 10 | 11 | * Readability 12 | 13 | * The purpose of Go: 14 | 15 | - The goals of the Go project were to eliminate the slowness and clumsiness of software development at Google. 16 | - To make the process more productive and scalable. 17 | -> The language was designed by and for people who write—and read and debug and maintain—large software systems. 18 | 19 | * Bad Function Arguments 20 | 21 | .code ./example/function/bad.go 22 | 23 | * What it looks like in My VSCode 24 | 25 | .image ./image/baddocfunction.png _ 1000 26 | 27 | * Autocomplete do their best 28 | 29 | .image ./image/typingfunction.png _ 1000 30 | 31 | * We can do it better 32 | 33 | .code ./example/function/good.go 34 | 35 | * Even better when group the arguments with the same data type 36 | 37 | .code ./example/function/better.go 38 | 39 | * Autocomplete help us to work more effective 40 | 41 | .image ./image/goodautocomplete.png _ 1000 42 | 43 | * Your Client want to separate normal product with promotion product when checkout 44 | 45 | - You add the flag isPromotion to check if the product is a promotion product 46 | - You pass the promotion flag into function CreateOrder argument 47 | 48 | * Your CreateOrder function will look like 49 | 50 | .code ./example/function/passbool.go 51 | 52 | * 6 months later, you modify this function because it changes again 53 | 54 | .code ./example/function/addrequestion.go 55 | 56 | * Should not pass the boolean into function parameters 57 | 58 | Instead, we can... 59 | 60 | * We can check for the bool value first, and choose what function to run 61 | 62 | .code ./example/function/switch.go 63 | 64 | * Go syntax inspired from C, which limits the code block in "{}" 65 | 66 | .code ./example/return/bad.go 67 | 68 | * Go code look better when we separate the block 69 | 70 | .code ./example/return/good.go 71 | 72 | * Now let's rewrite our processRequest function 73 | 74 | .code ./example/function/returnfirst.go 75 | 76 | * 1 month later, Client wants you to logs the order, see the Quote of Order 77 | 78 | .code ./example/function/addquote.go 79 | 80 | * 2 months later, Client wants to see the Transaction 81 | 82 | .code ./example/function/addtransaction.go 83 | 84 | * 3 months later, Client wants to see the Invoice 85 | 86 | .code ./example/function/addinvoice.go 87 | 88 | * Go lets you return multiple values, but not this way 89 | 90 | - Two to Three return value is good, keep it small 91 | - Assign a meaningful name to the return value 92 | 93 | * A much better version 94 | 95 | .code ./example/function/betterreturn.go 96 | 97 | * Type Conversion/Assertion 98 | 99 | * The reason why Go have those two type of type convert/assert 100 | 101 | - Go is a "static type" language 102 | - Go also have the interface, which is anything 103 | - Go lets you pass an interface as a function argument 104 | 105 | => _We_ _need_ _to_ _convert_ _interface_ _to_ _specific_ _type_ _to_ _process_ _further_ 106 | 107 | * Type Conversion 108 | 109 | A type conversion converts one *(non-interface)* type to another, e.g. a `var` `x` `uint8` to and int64 like `var` `id` `int64` `=` `int64(x)` 110 | 111 | `v` `=` `aType(t)` // type conversion 112 | 113 | * What if x cannot convert to int64 114 | 115 | .code ./example/conversion/notmatch.go 116 | 117 | * Type Assertion 118 | 119 | A type assertion asserts that t *(an* *interface* *type)* actually is an aType and t will be an aType; namely, the one wrapped in the t interface 120 | 121 | `v` `=` `t.(aType)` // type assertion 122 | 123 | * What if v is not aType 124 | 125 | .code ./example/assertion/notok.go 126 | 127 | * Luckily, Go give you the power to check whether interface not satisfy aType 128 | 129 | .code ./example/assertion/ok.go 130 | 131 | * The Power of Map 132 | 133 | .code ./example/map/assertion.go 134 | 135 | * We can use this tip to work with Enum output, Simplicity go first! 136 | 137 | * Recap 138 | 139 | - Go is an open source programming language that makes it easy to build *simple*, *reliable*, and *efficient* software. 140 | - An effective way to use a tool is to use it to do the purpose of it, keep your Go code: *simple*, *readable*, to be able to *maintain* -------------------------------------------------------------------------------- /17-VN-gophers-after-COVID/microservices-in-action/Microservices In Action - The Funzy Dev.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/17-VN-gophers-after-COVID/microservices-in-action/Microservices In Action - The Funzy Dev.pdf -------------------------------------------------------------------------------- /2016_04_12_HaNoi_TechTalk/Build Command Line Tool with Golang.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/2016_04_12_HaNoi_TechTalk/Build Command Line Tool with Golang.pdf -------------------------------------------------------------------------------- /2016_04_12_HaNoi_TechTalk/Go at FSoft.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/2016_04_12_HaNoi_TechTalk/Go at FSoft.pdf -------------------------------------------------------------------------------- /2016_04_12_HaNoi_TechTalk/Struct tags in Go.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/2016_04_12_HaNoi_TechTalk/Struct tags in Go.pdf -------------------------------------------------------------------------------- /2016_04_12_HaNoi_TechTalk/Use Queue to scale server performance.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/2016_04_12_HaNoi_TechTalk/Use Queue to scale server performance.pdf -------------------------------------------------------------------------------- /2016_04_12_HaNoi_TechTalk/What do people say when they switch to Go.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/2016_04_12_HaNoi_TechTalk/What do people say when they switch to Go.pdf -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Discord Chat](https://img.shields.io/discord/787711350809296916.svg)](https://discord.gg/xqHJEa5CSN) 2 | 3 | 4 | ## Golang Vietnam Meetup Wiki 5 | 6 | [![Meetup 01](https://raw.githubusercontent.com/golang-vietnam/meetup/master/images/cover.jpg)](/images/cover.jpg) 7 | 8 | The very first meetup event of Vietnamese Gophers with many helps from Dwarves Foundation, GDG Vietnam, Silicon Straits Saigon and Liti Solutions. 9 | 10 | We will introduce Google Go to you and announce the exist of our community. 11 | 12 | ### About us: 13 | 14 | Founded in 2014, this meetup is the place for all beginner and experienced #golang programmers in Vietnam. 15 | 16 | We meet on the second and fourth Tuesdays of the month. Second Tuesdays are for one or more talks, and fourth Tuesdays are just hackfests, where people bring their laptops and hang out. 17 | 18 | Discuss all #golang related topics, meet other developers and other interesting folks. Presentations, workshops, hack-fests and more. Meet other developers, find out about interesting projects and opportunities for work and potential employment. Join the group and you'll get a weekly newsletter with lots of great beginner material. 19 | 20 | 21 | ### Contact us at: 22 | 23 | - FB Group: https://www.facebook.com/groups/golangvietnam 24 | - FB Page: https://www.facebook.com/golang.org.vn 25 | - Github: https://github.com/golang-vietnam 26 | - Twitter: https://twitter.com/golangvietnam 27 | - Discord: [![Discord Chat](https://img.shields.io/discord/787711350809296916.svg)](https://discord.gg/xqHJEa5CSN) 28 | 29 | -------------------------------------------------------------------------------- /go-installfest/Go Installfest.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/go-installfest/Go Installfest.pdf -------------------------------------------------------------------------------- /images/cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/images/cover.jpg -------------------------------------------------------------------------------- /logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/logo.png -------------------------------------------------------------------------------- /logo.sketch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/logo.sketch -------------------------------------------------------------------------------- /template/template_01.key: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/template/template_01.key -------------------------------------------------------------------------------- /template/template_01.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-vietnam/meetup/687be6fcc262f3c0c2e966b5cb76e0fd44f418ea/template/template_01.pptx --------------------------------------------------------------------------------