├── live-reload ├── .gitignore ├── main.go ├── go.mod └── go.sum ├── fuzz ├── go.mod ├── contains.go └── contains_test.go ├── tests ├── go.mod ├── odd.go └── odd_test.go ├── benchmarks ├── go.mod ├── primeNumbers_test.go └── primeNumbers.go ├── consensus ├── go.mod ├── server ├── image.png ├── cmd │ └── server │ │ └── main.go └── pkg │ ├── raft │ ├── types.go │ ├── rpc.go │ └── node.go │ ├── store │ └── store.go │ └── api │ └── server.go ├── fundamentos-3 ├── go.mod ├── for │ ├── for-comum │ │ └── main.go │ └── for-com-range │ │ └── main.go ├── main.go ├── funcoes │ ├── funcao-anonima │ │ └── main.go │ ├── passando-funcao-por-parametro │ │ └── main.go │ ├── funcao-multiplo-retorno │ │ └── main.go │ └── passando-varios-valores-por-parametro │ │ └── main.go └── while │ ├── do-while │ └── main.go │ └── while-comum │ └── main.go ├── go1_19 ├── go.mod ├── errorsAs.go ├── atomicChanges.go ├── doc.go └── flagTextVar.go ├── watcher-files ├── configurations.yml ├── go.mod ├── go.sum └── watcher.go ├── errgroup ├── go.mod ├── go.sum └── main.go ├── rateLimit ├── go.mod ├── go.sum └── main.go ├── circuitBreak ├── go.mod ├── go.sum └── main.go ├── websocket_chat_app ├── go.mod ├── go.sum ├── main.go └── index.html ├── minha-primeira-api ├── go-chi │ ├── go.mod │ ├── go.sum │ └── main.go ├── gorilla-mux │ ├── go.mod │ ├── go.sum │ └── main.go ├── gin-gonic │ ├── main.go │ ├── go.mod │ └── go.sum ├── net-http │ └── main.go └── validando-dados │ ├── main.go │ ├── go.mod │ └── go.sum ├── bancos-de-dados ├── mysql │ ├── go.mod │ ├── go.sum │ └── main.go ├── elasticsearch │ ├── go.mod │ ├── go.sum │ └── main.go ├── cassandradb │ ├── go.mod │ ├── main.go │ └── go.sum └── mongodb │ ├── go.mod │ ├── main.go │ └── go.sum ├── copierConverter ├── go.mod ├── go.sum └── copier.go ├── executando-c-em-go ├── run-c-from-go-another-file │ ├── cgo2.c │ └── cgo2.go ├── run-go-from-c │ ├── cgo3.c │ └── cgo3.go └── run-c-from-go │ └── cgo1.go ├── formatFmt └── main.go ├── bad-things ├── interfaces.go ├── logs.go ├── syntax.go ├── format.go ├── go.mod ├── errorHandling.go └── go.sum ├── fundamentos-2 ├── if │ └── main.go ├── if-com-init │ └── main.go └── switch │ └── main.go ├── .gitignore ├── context ├── main_withvalue.go ├── main_withtimeout.go ├── main_withcancel.go └── main_withdeadline.go ├── panicRecover └── panicRecover.go ├── templateCode ├── main2.go └── main.go ├── ponteiros ├── main.c └── main.go ├── fundamentos-1 ├── structs │ └── main.go ├── arrays-slices │ └── main.go ├── tipos-variaveis │ └── main.go └── variaveis-publicas-e-privadas │ └── main.go ├── interfaces └── user_interface.go ├── debug └── main.go ├── b3TraceId ├── go.mod ├── main.go └── go.sum ├── telemetry ├── go.mod ├── main.go └── go.sum ├── test-containers ├── connect_test.go ├── test_container.go ├── connect.go ├── go.mod └── go.sum ├── generics └── main.go ├── error_handling ├── go.mod ├── main.go └── go.sum ├── LICENSE ├── calling-chatgpt-api └── main.go ├── stateMachine └── main.go ├── framework-performance-diff ├── go.mod ├── main.go ├── bench_framework_web_test.go └── go.sum ├── exponentialBackoff └── main.go └── reverseProxyNoCache └── main.go /live-reload/.gitignore: -------------------------------------------------------------------------------- 1 | .air.conf -------------------------------------------------------------------------------- /fuzz/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/golang-basics/fuzz 2 | -------------------------------------------------------------------------------- /tests/go.mod: -------------------------------------------------------------------------------- 1 | module tests-intro 2 | 3 | go 1.18 4 | -------------------------------------------------------------------------------- /benchmarks/go.mod: -------------------------------------------------------------------------------- 1 | module benchmarks 2 | 3 | go 1.19 4 | -------------------------------------------------------------------------------- /consensus/go.mod: -------------------------------------------------------------------------------- 1 | module consensus 2 | 3 | go 1.24.0 4 | -------------------------------------------------------------------------------- /fundamentos-3/go.mod: -------------------------------------------------------------------------------- 1 | module fundamentos 2 | 3 | go 1.16 4 | -------------------------------------------------------------------------------- /go1_19/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/HunCoding/golang-basics/go1_19 2 | 3 | go 1.18 4 | -------------------------------------------------------------------------------- /watcher-files/configurations.yml: -------------------------------------------------------------------------------- 1 | username: TESTE2 2 | lastname: test 3 | age: 50 -------------------------------------------------------------------------------- /consensus/server: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HunCoding/golang-basics/HEAD/consensus/server -------------------------------------------------------------------------------- /consensus/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HunCoding/golang-basics/HEAD/consensus/image.png -------------------------------------------------------------------------------- /errgroup/go.mod: -------------------------------------------------------------------------------- 1 | module errGroup 2 | 3 | go 1.23.2 4 | 5 | require golang.org/x/sync v0.8.0 6 | -------------------------------------------------------------------------------- /rateLimit/go.mod: -------------------------------------------------------------------------------- 1 | module rateLimit 2 | 3 | go 1.23.4 4 | 5 | require golang.org/x/time v0.8.0 6 | -------------------------------------------------------------------------------- /circuitBreak/go.mod: -------------------------------------------------------------------------------- 1 | module circuitBreaker 2 | 3 | go 1.23.4 4 | 5 | require github.com/sony/gobreaker v1.0.0 6 | -------------------------------------------------------------------------------- /websocket_chat_app/go.mod: -------------------------------------------------------------------------------- 1 | module websocket_chat_app 2 | 3 | go 1.21 4 | 5 | require github.com/gorilla/websocket v1.5.3 6 | -------------------------------------------------------------------------------- /minha-primeira-api/go-chi/go.mod: -------------------------------------------------------------------------------- 1 | module minha-primeira-api/go-chi 2 | 3 | go 1.18 4 | 5 | require github.com/go-chi/chi/v5 v5.0.7 6 | -------------------------------------------------------------------------------- /bancos-de-dados/mysql/go.mod: -------------------------------------------------------------------------------- 1 | module huncoding/bancos-de-dados/mysql 2 | 3 | go 1.18 4 | 5 | require github.com/go-sql-driver/mysql v1.6.0 6 | -------------------------------------------------------------------------------- /minha-primeira-api/gorilla-mux/go.mod: -------------------------------------------------------------------------------- 1 | module minha-primeira-api/gorilla-mux 2 | 3 | go 1.18 4 | 5 | require github.com/gorilla/mux v1.8.0 // indirect 6 | -------------------------------------------------------------------------------- /copierConverter/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/HunCoding/golang-basics/copierConverter 2 | 3 | go 1.19 4 | 5 | require github.com/jinzhu/copier v0.3.5 // indirect 6 | -------------------------------------------------------------------------------- /executando-c-em-go/run-c-from-go-another-file/cgo2.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void inCFile() { 4 | printf("I am in C code in a .c file now!\n"); 5 | } 6 | -------------------------------------------------------------------------------- /executando-c-em-go/run-go-from-c/cgo3.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void inCFile() { 4 | printf("I am in C code in a .c file now!\n"); 5 | callFromC(); 6 | } 7 | -------------------------------------------------------------------------------- /errgroup/go.sum: -------------------------------------------------------------------------------- 1 | golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= 2 | golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= 3 | -------------------------------------------------------------------------------- /rateLimit/go.sum: -------------------------------------------------------------------------------- 1 | golang.org/x/time v0.8.0 h1:9i3RxcPv3PZnitoVGMPDKZSq1xW1gK1Xy3ArNOGZfEg= 2 | golang.org/x/time v0.8.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= 3 | -------------------------------------------------------------------------------- /formatFmt/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "log" 4 | 5 | type Test struct { 6 | name string 7 | } 8 | 9 | func main() { 10 | 11 | log.Panic("test") 12 | 13 | } 14 | -------------------------------------------------------------------------------- /copierConverter/go.sum: -------------------------------------------------------------------------------- 1 | github.com/jinzhu/copier v0.3.5 h1:GlvfUwHk62RokgqVNvYsku0TATCF7bAHVwEXoBh3iJg= 2 | github.com/jinzhu/copier v0.3.5/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg= 3 | -------------------------------------------------------------------------------- /minha-primeira-api/go-chi/go.sum: -------------------------------------------------------------------------------- 1 | github.com/go-chi/chi/v5 v5.0.7 h1:rDTPXLDHGATaeHvVlLcR4Qe0zftYethFucbjVQ1PxU8= 2 | github.com/go-chi/chi/v5 v5.0.7/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= 3 | -------------------------------------------------------------------------------- /minha-primeira-api/gorilla-mux/go.sum: -------------------------------------------------------------------------------- 1 | github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= 2 | github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= 3 | -------------------------------------------------------------------------------- /websocket_chat_app/go.sum: -------------------------------------------------------------------------------- 1 | github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= 2 | github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= 3 | -------------------------------------------------------------------------------- /bancos-de-dados/mysql/go.sum: -------------------------------------------------------------------------------- 1 | github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= 2 | github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= 3 | -------------------------------------------------------------------------------- /tests/odd.go: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | var ( 4 | ODD_KEYWORD = "ODD" 5 | EVEN_KEYWORD = "EVEN" 6 | ) 7 | 8 | func IsOdd(value int64) string { 9 | if value%2 == 0 { 10 | return EVEN_KEYWORD 11 | } 12 | 13 | return ODD_KEYWORD 14 | } 15 | -------------------------------------------------------------------------------- /executando-c-em-go/run-c-from-go-another-file/cgo2.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | /* 4 | extern void inCFile(); 5 | */ 6 | import "C" 7 | 8 | import "fmt" 9 | 10 | func main() { 11 | fmt.Println("I am in Go code now!") 12 | C.inCFile() 13 | } 14 | -------------------------------------------------------------------------------- /watcher-files/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/HunCoding/golang-basics/watcher-files 2 | 3 | go 1.19 4 | 5 | require ( 6 | github.com/fsnotify/fsnotify v1.6.0 7 | gopkg.in/yaml.v2 v2.4.0 8 | ) 9 | 10 | require golang.org/x/sys v0.0.0-20220908164124-27713097b956 // indirect 11 | -------------------------------------------------------------------------------- /go1_19/errorsAs.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | ) 7 | 8 | func errorsAsError() { 9 | var newErr = errors.New("sentinel") 10 | var err = errors.New("foo") 11 | 12 | if errors.As(err, newErr) { 13 | fmt.Println("error here!") 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /bad-things/interfaces.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | type User struct { 4 | Name string 5 | } 6 | 7 | var interfaceUser UserInterface = &User{} 8 | 9 | type UserInterface interface { 10 | GetUserName() string 11 | } 12 | 13 | func (u *User) GetUserName() string { 14 | return u.Name 15 | } 16 | -------------------------------------------------------------------------------- /bad-things/logs.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func log() { 6 | fmt.Printf( 7 | "action=FindUserByIdAndName, message=init, userId=%s, userName=%s, error=Error trying to get user by id and name, trace=MongoDB timeout", 8 | "123455", 9 | "HUNCODING", 10 | ) 11 | } 12 | -------------------------------------------------------------------------------- /fundamentos-2/if/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | 7 | test := "test" 8 | 9 | if test == "test" { 10 | fmt.Println("Caiu no if") 11 | } else if test == "test2" { 12 | fmt.Println("Caiu no else if") 13 | } else { 14 | fmt.Println("Caiu no else") 15 | 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /fundamentos-3/for/for-comum/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | 7 | listOfValues := []string{"test", "test", "test"} 8 | 9 | for i := 0; i < len(listOfValues); i++ { 10 | fmt.Println(fmt.Sprintf("Valor atual: %s, indice do valor: %d", listOfValues[i], i)) 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /bancos-de-dados/elasticsearch/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/HunCoding/bancos-de-dados/elasticsearch 2 | 3 | go 1.18 4 | 5 | require ( 6 | github.com/elastic/go-elasticsearch v0.0.0 7 | github.com/elastic/go-elasticsearch/v8 v8.1.0 8 | ) 9 | 10 | require github.com/elastic/elastic-transport-go/v8 v8.1.0 // indirect 11 | -------------------------------------------------------------------------------- /minha-primeira-api/go-chi/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "net/http" 5 | 6 | "github.com/go-chi/chi/v5" 7 | ) 8 | 9 | func main() { 10 | r := chi.NewRouter() 11 | r.Get("/", func(w http.ResponseWriter, r *http.Request) { 12 | w.Write([]byte("welcome")) 13 | }) 14 | http.ListenAndServe(":8080", r) 15 | } 16 | -------------------------------------------------------------------------------- /bancos-de-dados/cassandradb/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/HunCoding/bancos-de-dados/cassandradb 2 | 3 | go 1.18 4 | 5 | require github.com/gocql/gocql v1.0.0 6 | 7 | require ( 8 | github.com/golang/snappy v0.0.3 // indirect 9 | github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed // indirect 10 | gopkg.in/inf.v0 v0.9.1 // indirect 11 | ) 12 | -------------------------------------------------------------------------------- /executando-c-em-go/run-go-from-c/cgo3.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | /* 4 | extern void inCFile(); 5 | */ 6 | import "C" 7 | 8 | import "fmt" 9 | 10 | func main() { 11 | fmt.Println("I am in Go code now!") 12 | C.inCFile() 13 | } 14 | 15 | //export callFromC 16 | func callFromC() { 17 | fmt.Println("I am in Go code but I was called from C!") 18 | } 19 | -------------------------------------------------------------------------------- /minha-primeira-api/gin-gonic/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/gin-gonic/gin" 7 | ) 8 | 9 | func main() { 10 | 11 | router := gin.Default() 12 | 13 | router.GET("/test", func(ctx *gin.Context) { 14 | fmt.Println(ctx.Request.Header) 15 | ctx.String(200, "ok") 16 | }) 17 | 18 | router.Run(":9091") 19 | } 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | *.dll 5 | *.so 6 | *.dylib 7 | 8 | # Test binary, built with `go test -c` 9 | *.test 10 | 11 | # Output of the go coverage tool, specifically when used with LiteIDE 12 | *.out 13 | 14 | .idea/ 15 | 16 | # Dependency directories (remove the comment below to include it) 17 | # vendor/ 18 | -------------------------------------------------------------------------------- /go1_19/atomicChanges.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "sync/atomic" 6 | ) 7 | 8 | func atomicChanges() { 9 | // Antes da versao 1.19 10 | //var i int64 11 | //atomic.AddInt64(&i, 10) 12 | //fmt.Println(atomic.LoadInt64(&i)) 13 | 14 | //Depois da versao 1.19 15 | var i atomic.Int64 16 | i.Add(10) 17 | fmt.Println(i.Load()) 18 | } 19 | -------------------------------------------------------------------------------- /context/main_withvalue.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | ) 7 | 8 | func main() { 9 | ctx := context.WithValue( 10 | context.Background(), 11 | "testKey", 12 | "testValue", 13 | ) 14 | 15 | printUntilCancel(ctx) 16 | } 17 | 18 | func printUntilCancel(ctx context.Context) { 19 | fmt.Println(ctx.Value("testKey")) 20 | } 21 | -------------------------------------------------------------------------------- /panicRecover/panicRecover.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func assertValue(value1 string, value2 string) { 6 | if value1 == value2 { 7 | fmt.Println("Sao iguais") 8 | } 9 | 10 | panic("Nao sao iguais") 11 | } 12 | 13 | func main() { 14 | try { 15 | assertValue("hun", "coding") 16 | } catch(e Exception) { 17 | fmt.Println 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /templateCode/main2.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | type Person struct { 6 | Name string 7 | Youtube string 8 | 9 | } 10 | 11 | func printStruct(s Person) { 12 | fmt.Println(s) 13 | } 14 | 15 | func main() { 16 | s := Person{ 17 | Name: "John", 18 | Youtube: "youtube.com/@huncoding", 19 | 20 | } 21 | 22 | printStruct(s) 23 | } 24 | -------------------------------------------------------------------------------- /executando-c-em-go/run-c-from-go/cgo1.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | //#include 4 | //void inC(int a, int b) { 5 | // printf("Valor somado: %d", a + b); 6 | // printf("I am in C code now!\n"); 7 | //} 8 | import "C" 9 | 10 | import "fmt" 11 | 12 | func main() { 13 | fmt.Println("I am in Go code now!") 14 | a := C.int(2) 15 | b := C.int(3) 16 | C.inC(a, b) 17 | } 18 | -------------------------------------------------------------------------------- /fundamentos-3/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | 7 | testParametro2 := func() { 8 | fmt.Println("test2") 9 | } 10 | testParametro := func() { 11 | fmt.Println("test") 12 | } 13 | test(testParametro, testParametro2) 14 | 15 | } 16 | 17 | func test(valoresString ...func()) { 18 | 19 | for _, x := range valoresString { 20 | x() 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /live-reload/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/gin-gonic/gin" 7 | ) 8 | 9 | func main() { 10 | router := gin.Default() 11 | 12 | router.GET("/test", func(c *gin.Context) { 13 | value := c.Query("channel") 14 | fmt.Println(value) 15 | 16 | c.String(200, fmt.Sprintf("Seu canal se chama %s", value)) 17 | }) 18 | 19 | router.Run(":8080") 20 | } 21 | -------------------------------------------------------------------------------- /ponteiros/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | void main() 3 | { 4 | int a; 5 | int b; 6 | int c; 7 | int *ptr; // declara um ponteiro para um inteiro 8 | // um ponteiro para uma variável do tipo inteiro 9 | a = 90; 10 | b = 2; 11 | c = 3; 12 | ptr = &a; 13 | printf("Valor de ptr: %p, Conteúdo de ptr: %d\n", ptr, *ptr); 14 | printf("B: %d, C: %d"), b, c); 15 | } 16 | -------------------------------------------------------------------------------- /bad-things/syntax.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | type Valores struct { 4 | x int //nao precisa ter virgula 5 | y int 6 | } 7 | 8 | func inverterValores(x, y int) (int, int) { //aqui sao obrigatorios os parenteses 9 | return y, x //mas aqui nao 10 | } 11 | 12 | func syntaxExample() { 13 | _ = Valores{ 14 | x: 50, 15 | y: 100, // por que precisa de virgula no ultimo parametro? 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /fundamentos-1/structs/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | 7 | userVar := user{ 8 | name: "test", 9 | age: 20, 10 | test2: "test2", 11 | } 12 | 13 | testVar := test{} 14 | 15 | fmt.Println(userVar) 16 | fmt.Println(testVar) 17 | 18 | } 19 | 20 | type test struct { 21 | } 22 | 23 | type user struct { 24 | name string 25 | age int 26 | test2 string 27 | } 28 | -------------------------------------------------------------------------------- /fundamentos-3/funcoes/funcao-anonima/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | 7 | // Executando funcao anonima dentro de outra funcao 8 | func(valueString string, valueInt int) { 9 | fmt.Println(valueString, valueInt) 10 | }("TEST TEST", 300) 11 | 12 | // Executando funcao anonima dentro de outra funcao 13 | func() { 14 | fmt.Println("EXECUTANDO DE DENTRO DA FUNCAO ANONIMA") 15 | }() 16 | } 17 | -------------------------------------------------------------------------------- /fuzz/contains.go: -------------------------------------------------------------------------------- 1 | package fuzz 2 | 3 | import ( 4 | "strings" 5 | ) 6 | 7 | func MyIndexAny(s, chars string) int { 8 | /* 9 | Passa por todos os caracteres da palavra s e verificar 10 | quantas vezes "chars" aparece dentro dela 11 | */ 12 | for i, c := range s { 13 | if strings.ContainsRune(chars, c) { 14 | return i 15 | } 16 | } 17 | 18 | /* 19 | Se não existe nenhuma, retorna -1 20 | */ 21 | return -1 22 | } 23 | -------------------------------------------------------------------------------- /fundamentos-3/while/do-while/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | 7 | anExpression := false 8 | 9 | //Aqui o codigo vai passar uma vez e vai sair, pois como e um do-while 10 | //ele vai executar uma vez, validar, ver que a validacao esta incorreta 11 | //e assim ele vai sair do for 12 | for ok := true; ok; ok = anExpression { 13 | fmt.Println("Passou aqui mesmo com validacao incorreta") 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /interfaces/user_interface.go: -------------------------------------------------------------------------------- 1 | package interfaces 2 | 3 | type User struct { 4 | ID string 5 | Name string 6 | } 7 | 8 | type UserMethods interface { 9 | GetUserById(id string) 10 | InsertUser(name string) 11 | } 12 | 13 | func (u *User) GetUserById(id string) {} 14 | func (u *User) InsertUser(name string) {} 15 | 16 | type UserMock struct{} 17 | 18 | func (u *UserMock) GetUserById(id string) {} 19 | func (u *UserMock) InsertUser(name string) {} 20 | -------------------------------------------------------------------------------- /fundamentos-2/if-com-init/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | ) 7 | 8 | func main() { 9 | 10 | if test, err := funcaoTest(); err != nil { 11 | fmt.Println(test, err) 12 | } 13 | 14 | if test, err := funcaoTest2(); err != nil { 15 | fmt.Println(test, err) 16 | } 17 | } 18 | 19 | func funcaoTest() (string, error) { 20 | return "", errors.New("Test") 21 | } 22 | 23 | func funcaoTest2() (string, error) { 24 | return "test", nil 25 | } 26 | -------------------------------------------------------------------------------- /minha-primeira-api/gorilla-mux/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "net/http" 5 | 6 | "github.com/gorilla/mux" 7 | ) 8 | 9 | func main() { 10 | r := mux.NewRouter() 11 | r.HandleFunc("/", func( 12 | rw http.ResponseWriter, 13 | req *http.Request) { 14 | 15 | rw.Header().Set("Content-Type", "application/json") 16 | rw.WriteHeader(http.StatusOK) 17 | rw.Write([]byte("123")) 18 | return 19 | }).Methods("GET", "POST") 20 | 21 | http.ListenAndServe(":8081", r) 22 | } 23 | -------------------------------------------------------------------------------- /fundamentos-3/for/for-com-range/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | 7 | //Definindo a lista na qual o for vai iterar 8 | listOfStringValues := []string{"test", "test", "test"} 9 | 10 | // O range retorna dois valores, o primeiro deles sendo o indice 11 | // e o segundo sendo o valor em si dentro da lista na qual voce 12 | // esta iterando 13 | for i, value := range listOfStringValues { 14 | fmt.Println(fmt.Sprintf("Valor: %s, indice: %d", value, i)) 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /ponteiros/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | 7 | var testValue string = "Otavio" 8 | copyStringVALUE(testValue) 9 | fmt.Println(testValue) 10 | 11 | originalStringValue(&testValue) 12 | fmt.Println(testValue) 13 | 14 | } 15 | 16 | func copyStringVALUE(stringValue string) { 17 | stringValue = "TEST" 18 | fmt.Println(stringValue) 19 | } 20 | 21 | func originalStringValue(stringValue *string) { 22 | *stringValue = "TEST" 23 | fmt.Println(*stringValue) 24 | 25 | } 26 | -------------------------------------------------------------------------------- /fundamentos-2/switch/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | 7 | test := "TEST_TEST" 8 | 9 | switch test { 10 | 11 | case "test", "test2", "test434", "test1323": 12 | fmt.Print("CAIU NA PRIMEIRA CONDICAO") 13 | fallthrough 14 | 15 | case "test_case_2": 16 | fmt.Println("CAIU NA SEGUNDA CONDIÇÃO") 17 | fallthrough 18 | 19 | case "test_case_3": 20 | fmt.Println("CAIU NA TERCEIRA CONDIÇÃO") 21 | break 22 | 23 | default: 24 | fmt.Println("CAIU NO DEFAULT") 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /debug/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math/rand" 6 | ) 7 | 8 | type RandomNumber = int64 9 | 10 | func main() { 11 | var randomNumber RandomNumber 12 | fmt.Println("Estou debuggando codigo em Go!") 13 | fmt.Printf("Valor atual da variavel: %d \n", randomNumber) 14 | 15 | randomNumber = 20 16 | addNumber(&randomNumber) 17 | 18 | fmt.Printf("Novo valor da variavel: %d \n", randomNumber) 19 | } 20 | 21 | func addNumber(randomNumber *RandomNumber) { 22 | randNumber := int64(rand.Intn(1000)) 23 | 24 | *randomNumber += randNumber 25 | } 26 | -------------------------------------------------------------------------------- /fundamentos-1/arrays-slices/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | var testSlice []string = []string{} 7 | var testArray [2]string = [2]string{"test", "test2"} 8 | 9 | fmt.Println(testSlice, testArray) 10 | 11 | // Printando a capacidade e o tamanho atual do 12 | // slice, para em seguida, inserir mais um valor 13 | // para comparar os novos tamanhos 14 | fmt.Println(cap(testSlice)) 15 | fmt.Println(len(testSlice)) 16 | 17 | testSlice = append(testSlice, "testValorAppend") 18 | 19 | fmt.Println(cap(testSlice)) 20 | fmt.Println(len(testSlice)) 21 | } 22 | -------------------------------------------------------------------------------- /b3TraceId/go.mod: -------------------------------------------------------------------------------- 1 | module b3TraceId 2 | 3 | go 1.23.2 4 | 5 | require ( 6 | go.opentelemetry.io/contrib/propagators/b3 v1.32.0 7 | go.opentelemetry.io/otel v1.32.0 8 | go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.32.0 9 | go.opentelemetry.io/otel/sdk v1.32.0 10 | ) 11 | 12 | require ( 13 | github.com/go-logr/logr v1.4.2 // indirect 14 | github.com/go-logr/stdr v1.2.2 // indirect 15 | github.com/google/uuid v1.6.0 // indirect 16 | go.opentelemetry.io/otel/metric v1.32.0 // indirect 17 | go.opentelemetry.io/otel/trace v1.32.0 // indirect 18 | golang.org/x/sys v0.27.0 // indirect 19 | ) 20 | -------------------------------------------------------------------------------- /fundamentos-1/tipos-variaveis/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | 7 | var testInt8 int = 3 8 | var testInt16 int16 = 3 9 | var testInt32 int32 = 3 10 | var testInt64 int64 = 3 11 | var testString string = "test" 12 | var testFloat32 float32 = 32.3 13 | var testFloat64 float64 = 32.3 14 | var testinterface interface{} = 32.3 15 | 16 | fmt.Println(testInt8) 17 | fmt.Println(testInt16) 18 | fmt.Println(testInt32) 19 | fmt.Println(testInt64) 20 | fmt.Println(testString) 21 | fmt.Println(testFloat32) 22 | fmt.Println(testFloat64) 23 | fmt.Println(testinterface) 24 | } 25 | -------------------------------------------------------------------------------- /telemetry/go.mod: -------------------------------------------------------------------------------- 1 | module telemetry 2 | 3 | go 1.23.2 4 | 5 | require ( 6 | go.opentelemetry.io/otel v1.32.0 7 | go.opentelemetry.io/otel/sdk v1.32.0 8 | go.opentelemetry.io/otel/trace v1.32.0 9 | ) 10 | 11 | require ( 12 | github.com/go-logr/logr v1.4.2 // indirect 13 | github.com/go-logr/stdr v1.2.2 // indirect 14 | github.com/google/uuid v1.6.0 // indirect 15 | go.opentelemetry.io/otel/exporters/jaeger v1.17.0 // indirect 16 | go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.32.0 // indirect 17 | go.opentelemetry.io/otel/metric v1.32.0 // indirect 18 | golang.org/x/sys v0.27.0 // indirect 19 | ) 20 | -------------------------------------------------------------------------------- /bancos-de-dados/elasticsearch/go.sum: -------------------------------------------------------------------------------- 1 | github.com/elastic/elastic-transport-go/v8 v8.1.0 h1:NeqEz1ty4RQz+TVbUrpSU7pZ48XkzGWQj02k5koahIE= 2 | github.com/elastic/elastic-transport-go/v8 v8.1.0/go.mod h1:87Tcz8IVNe6rVSLdBux1o/PEItLtyabHU3naC7IoqKI= 3 | github.com/elastic/go-elasticsearch v0.0.0 h1:Pd5fqOuBxKxv83b0+xOAJDAkziWYwFinWnBO0y+TZaA= 4 | github.com/elastic/go-elasticsearch v0.0.0/go.mod h1:TkBSJBuTyFdBnrNqoPc54FN0vKf5c04IdM4zuStJ7xg= 5 | github.com/elastic/go-elasticsearch/v8 v8.1.0 h1:6TLhYoes04FRK83GakeuMsOQsx1qRwXdP/LF1nxfx1U= 6 | github.com/elastic/go-elasticsearch/v8 v8.1.0/go.mod h1:yY52i2Vj0unLz+N3Nwx1gM5LXwoj3h2dgptNGBYkMLA= 7 | -------------------------------------------------------------------------------- /context/main_withtimeout.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | // func main() { 4 | // ctx, cancel := context.WithTimeout( 5 | // context.Background(), 6 | // 5*time.Second, 7 | // ) 8 | // go printUntilCancel(ctx) 9 | // cancel() 10 | // } 11 | 12 | // func printUntilCancel(ctx context.Context) { 13 | // count := 0 14 | // for { 15 | // select { 16 | // case <-ctx.Done(): 17 | // fmt.Println("Cancel signal received, exiting") 18 | // return 19 | // default: 20 | // time.Sleep(1 * time.Second) 21 | // fmt.Printf("Printing until cancel, number = %d \n", count) 22 | // count += 1 23 | // } 24 | // } 25 | // } 26 | -------------------------------------------------------------------------------- /context/main_withcancel.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | // func main() { 4 | // ctx, cancel := context.WithCancel( 5 | // context.Background(), 6 | // ) 7 | // go printUntilCancel(ctx) 8 | 9 | // cancel() 10 | 11 | // time.Sleep(10 * time.Second) 12 | // } 13 | 14 | // func printUntilCancel(ctx context.Context) { 15 | // count := 0 16 | // for { 17 | // select { 18 | // case <-ctx.Done(): 19 | // fmt.Println("Cancel signal received, exiting") 20 | // return 21 | // default: 22 | // time.Sleep(1 * time.Second) 23 | // fmt.Printf("Printing until cancel, number = %d \n", count) 24 | // count += 1 25 | // } 26 | // } 27 | // } 28 | -------------------------------------------------------------------------------- /context/main_withdeadline.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | // func main() { 4 | // ctx, cancel := context.WithDeadline( 5 | // context.Background(), 6 | // time.Now().Add(10*time.Second), 7 | // ) 8 | // go printUntilCancel(ctx) 9 | // cancel() 10 | // } 11 | 12 | // func printUntilCancel(ctx context.Context) { 13 | // count := 0 14 | // for { 15 | // select { 16 | // case <-ctx.Done(): 17 | // fmt.Println("Cancel signal received, exiting") 18 | // return 19 | // default: 20 | // time.Sleep(1 * time.Second) 21 | // fmt.Printf("Printing until cancel, number = %d \n", count) 22 | // count += 1 23 | // } 24 | // } 25 | // } 26 | -------------------------------------------------------------------------------- /fundamentos-1/variaveis-publicas-e-privadas/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | var ( 6 | TestPublica = "test" 7 | testPrivada = "test" 8 | ) 9 | 10 | func main() { 11 | 12 | /* 13 | 14 | Como estamos no mesmo pacote, mesmo sendo privada ainda assim é acessivel aqui dentro 15 | porem, ao criar novos pacotes, a variavel testPrivada e a funcao "funcaoPrivada" não 16 | será visivel 17 | 18 | */ 19 | 20 | funcaoPrivada() 21 | FuncaoPublica() 22 | 23 | fmt.Println(TestPublica) 24 | fmt.Println(testPrivada) 25 | 26 | } 27 | 28 | func funcaoPrivada() { 29 | return 30 | } 31 | 32 | func FuncaoPublica() { 33 | 34 | } 35 | -------------------------------------------------------------------------------- /go1_19/doc.go: -------------------------------------------------------------------------------- 1 | package go1_19 2 | 3 | import "fmt" 4 | 5 | // # This is not a heading, because there is no space. 6 | // 7 | // # This is not a heading, 8 | // # because it is multiple lines. 9 | // 10 | // # This is not a heading, 11 | // because it is also multiple lines. 12 | // 13 | // The next paragraph is not a heading, because there is no additional text: 14 | // 15 | // # 16 | // 17 | // In the middle of a span of non-blank lines, 18 | // # this is not a heading either. 19 | // 20 | // # This is not a heading, because it is indented. 21 | func NewPseudoVersion() { 22 | fmt.Println("Print from new version") 23 | } 24 | 25 | func PrintHello() {} 26 | -------------------------------------------------------------------------------- /fundamentos-3/while/while-comum/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | 7 | // Definindo o valor inicial para comecar o codigo do for com valor 0 8 | testValue := 0 9 | 10 | // Enquanto testValue for menor ou igual a 20, ele vai executar o codigo que estiver dentro das chaves 11 | // Similar a outras linguagens nas quais voce faz: 12 | /* 13 | 14 | while (testValue <= 20) { 15 | 16 | } 17 | 18 | */ 19 | for testValue <= 20 { 20 | fmt.Println(fmt.Sprintf("Valor atual: %d", testValue)) 21 | 22 | // Adiciona 1 toda vez que passa pelo codigo, para assim, nao entrar em loop infinito 23 | testValue++ 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /benchmarks/primeNumbers_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | var num = 100 9 | 10 | var table = []struct { 11 | input int 12 | }{ 13 | {input: 100}, 14 | {input: 1000}, 15 | {input: 74382}, 16 | {input: 382399}, 17 | } 18 | 19 | func BenchmarkPrimeNumbersCoding(b *testing.B) { 20 | // mock 21 | for i := 0; i < b.N; i++ { 22 | primeNumbers(num) 23 | } 24 | } 25 | 26 | func BenchmarkPrimeNumbersImproved(b *testing.B) { 27 | for _, v := range table { 28 | b.Run(fmt.Sprintf("input_size_%d", v.input), func(b *testing.B) { 29 | for i := 0; i < b.N; i++ { 30 | isPrimeImproved(v.input) 31 | } 32 | }) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /fundamentos-3/funcoes/passando-funcao-por-parametro/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | 7 | funcaoTesteParametro := func(valueString string, valueInt int) { 8 | fmt.Println(valueString, valueInt) 9 | } 10 | 11 | testFunctionByParameter(funcaoTesteParametro) 12 | 13 | funcao := returningFunctions() 14 | 15 | funcao("TEST", 4000) 16 | 17 | } 18 | 19 | func returningFunctions() func(string, int) { 20 | funcaoTestRetorno := func(valueString string, valueInt int) { 21 | fmt.Println(valueString, valueInt) 22 | } 23 | 24 | return funcaoTestRetorno 25 | } 26 | 27 | func testFunctionByParameter(funcaoTest func(string, int)) { 28 | funcaoTest("TEST TEST", 20) 29 | } 30 | -------------------------------------------------------------------------------- /fundamentos-3/funcoes/funcao-multiplo-retorno/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | 7 | testMultipleReturnString, testMultipleReturnInt := returnTwoValues() 8 | testMultipleNamedValuesString, testMultipleNamedReturnInt := returnNamedValues() 9 | 10 | fmt.Println(testMultipleNamedReturnInt, testMultipleNamedValuesString) 11 | fmt.Println(testMultipleReturnInt, testMultipleReturnString) 12 | 13 | } 14 | 15 | func returnTwoValues() (string, int) { 16 | 17 | return "TEST", 20 18 | 19 | } 20 | 21 | func returnNamedValues() (returnStringValue string, returnIntValue int) { 22 | 23 | returnIntValue = 20 24 | returnStringValue = "TEST NAMED RETURN VALUE" 25 | 26 | return 27 | 28 | } 29 | -------------------------------------------------------------------------------- /bad-things/format.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func format() { 6 | 7 | hun := "Hun" 8 | coding := "Coding" 9 | 10 | //Concatenar duas variaveis 11 | _ = fmt.Sprintf("Concat: %s%#v", hun, coding) 12 | 13 | //Printar duas variaveis e criar uma nova linha 14 | fmt.Printf("Concat: %s%s\n", hun, coding) 15 | //ou 16 | fmt.Println(fmt.Sprintf("Concat: %s%s", hun, coding)) 17 | 18 | fmt.Println("Text extenso") 19 | 20 | /* 21 | Precisava ser assim, sera? Acaba sendo uma complicação que hoje nao faz sentido ter. 22 | 23 | JavaScript 24 | console.log(`Concat: ${hun + coding}`) 25 | 26 | Rust 27 | println!("Concat: {}{}", hun, coding) 28 | 29 | Python 30 | print(f'Concat ${hun + coding}') 31 | */ 32 | } 33 | -------------------------------------------------------------------------------- /watcher-files/go.sum: -------------------------------------------------------------------------------- 1 | github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= 2 | github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= 3 | golang.org/x/sys v0.0.0-20220908164124-27713097b956 h1:XeJjHH1KiLpKGb6lvMiksZ9l0fVUh+AmGcm0nOMEBOY= 4 | golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 5 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= 6 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 7 | gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= 8 | gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= 9 | -------------------------------------------------------------------------------- /bancos-de-dados/mongodb/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/HunCoding/bancos-de-dados/mysql/mongodb 2 | 3 | go 1.18 4 | 5 | require ( 6 | github.com/go-stack/stack v1.8.0 // indirect 7 | github.com/golang/snappy v0.0.1 // indirect 8 | github.com/klauspost/compress v1.13.6 // indirect 9 | github.com/pkg/errors v0.9.1 // indirect 10 | github.com/xdg-go/pbkdf2 v1.0.0 // indirect 11 | github.com/xdg-go/scram v1.0.2 // indirect 12 | github.com/xdg-go/stringprep v1.0.2 // indirect 13 | github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect 14 | go.mongodb.org/mongo-driver v1.8.4 // indirect 15 | golang.org/x/crypto v0.0.0-20201216223049-8b5274cf687f // indirect 16 | golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e // indirect 17 | golang.org/x/text v0.3.5 // indirect 18 | ) 19 | -------------------------------------------------------------------------------- /benchmarks/primeNumbers.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "math" 4 | 5 | // credits: blog.logrocket 6 | func primeNumbers(max int) []int { 7 | var primes []int 8 | 9 | for i := 2; i < max; i++ { 10 | isPrime := true 11 | 12 | for j := 2; j <= int(math.Sqrt(float64(i))); j++ { 13 | if i%j == 0 { 14 | isPrime = false 15 | break 16 | } 17 | } 18 | 19 | if isPrime { 20 | primes = append(primes, i) 21 | } 22 | } 23 | 24 | return primes 25 | } 26 | 27 | func isPrimeImproved(max int) []int { 28 | b := make([]bool, max) 29 | 30 | var primes []int 31 | 32 | for i := 2; i < max; i++ { 33 | if b[i] { 34 | continue 35 | } 36 | 37 | primes = append(primes, i) 38 | 39 | for k := i * i; k < max; k += i { 40 | b[k] = true 41 | } 42 | } 43 | 44 | return primes 45 | } 46 | -------------------------------------------------------------------------------- /circuitBreak/go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= 2 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 4 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 5 | github.com/sony/gobreaker v1.0.0 h1:feX5fGGXSl3dYd4aHZItw+FpHLvvoaqkawKjVNiFMNQ= 6 | github.com/sony/gobreaker v1.0.0/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= 7 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 8 | github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= 9 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 10 | -------------------------------------------------------------------------------- /minha-primeira-api/net-http/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "html" 6 | "log" 7 | "net/http" 8 | ) 9 | 10 | func main() { 11 | 12 | httpObj := NewHttpInterface() 13 | 14 | http.Handle("/foo", httpObj) 15 | 16 | http.HandleFunc("/bar", func(w http.ResponseWriter, r *http.Request) { 17 | switch r.Method { 18 | case "POST": 19 | case "PATCH": 20 | } 21 | fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path)) 22 | }) 23 | 24 | log.Fatal(http.ListenAndServe(":8080", nil)) 25 | } 26 | 27 | type HttpStructImplementation struct { 28 | } 29 | 30 | func NewHttpInterface() http.Handler { 31 | return &HttpStructImplementation{} 32 | } 33 | 34 | func (h *HttpStructImplementation) ServeHTTP(rw http.ResponseWriter, req *http.Request) { 35 | rw.Header().Set("Content-Type", "application/json") 36 | rw.WriteHeader(http.StatusOK) 37 | rw.Write([]byte("123")) 38 | return 39 | } 40 | -------------------------------------------------------------------------------- /test-containers/connect_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "go.mongodb.org/mongo-driver/bson/primitive" 6 | "os" 7 | "testing" 8 | 9 | "go.mongodb.org/mongo-driver/bson" 10 | ) 11 | 12 | func TestMain(m *testing.M) { 13 | closeConnection := OpenConnection() 14 | defer closeConnection() 15 | os.Exit(m.Run()) 16 | } 17 | 18 | func TestCreateUser(t *testing.T) { 19 | testUser, err := CreateUser("test") 20 | if err != nil { 21 | t.FailNow() 22 | return 23 | } 24 | 25 | if testUser.Name != "test" { 26 | t.FailNow() 27 | return 28 | } 29 | 30 | hex, err := primitive.ObjectIDFromHex(testUser.ID) 31 | if err != nil { 32 | return 33 | } 34 | filter := bson.D{{Key: "_id", Value: hex}} 35 | result := Collection.FindOne(context.Background(), filter) 36 | user := User{} 37 | err = result.Decode(&user) 38 | if err != nil { 39 | t.FailNow() 40 | return 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /tests/odd_test.go: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | import "testing" 4 | 5 | // Test 6 | func TestIsOdd_return_odd(t *testing.T) { 7 | // Definindo varias 8 | var value int64 = 3 9 | 10 | //Chamar as funcoes necessarios 11 | number_type := IsOdd(value) 12 | 13 | //Verificar se o resultado foi conforme esperado 14 | if number_type != ODD_KEYWORD { 15 | t.Errorf("%s - expected %s, received %s", 16 | t.Name(), 17 | ODD_KEYWORD, 18 | number_type, 19 | ) 20 | return 21 | } 22 | } 23 | 24 | func TestIsOdd_return_even(t *testing.T) { 25 | // Definindo varias 26 | var value int64 = 4 27 | 28 | //Chamar as funcoes necessarios 29 | number_type := IsOdd(value) 30 | 31 | //Verificar se o resultado foi conforme esperado 32 | if number_type != EVEN_KEYWORD { 33 | t.Errorf("%s - expected %s, received %s", 34 | t.Name(), 35 | EVEN_KEYWORD, 36 | number_type, 37 | ) 38 | return 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /generics/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | type User[T any, B any] struct { 6 | name T 7 | age B 8 | } 9 | 10 | func testComparable[T comparable](arg1 T, arg2 T) bool { 11 | return arg1 == arg2 12 | } 13 | 14 | type NumberTest interface { 15 | int64 | float64 | float32 16 | } 17 | 18 | func testComparingNumbers[T NumberTest](arg1 T, arg2 T) bool { 19 | return arg1 > arg2 20 | } 21 | 22 | type TestImplementInt int64 23 | 24 | func testTokenImplement[T ~int64](arg1 T) { 25 | fmt.Println(arg1) 26 | } 27 | 28 | func main() { 29 | 30 | userTest := User[string, int64]{ 31 | name: "test", 32 | age: 20, 33 | } 34 | fmt.Println(userTest) 35 | 36 | fmt.Println(testComparable(20, 20)) 37 | 38 | var testNumberInt64 int64 = 20 39 | fmt.Println(testComparingNumbers(testNumberInt64, testNumberInt64)) 40 | 41 | var testImplement TestImplementInt = 30 42 | testTokenImplement(testImplement) 43 | 44 | } 45 | -------------------------------------------------------------------------------- /minha-primeira-api/validando-dados/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | 7 | "github.com/gin-gonic/gin" 8 | "github.com/go-playground/validator/v10" 9 | ) 10 | 11 | type User struct { 12 | Name string `json:"name" validate:"required"` 13 | Age int32 `json:"age" validate:"required,min=0,max=130"` 14 | } 15 | 16 | func main() { 17 | 18 | r := gin.Default() 19 | 20 | r.POST("/welcome", func(c *gin.Context) { 21 | 22 | var user User 23 | 24 | if err := c.ShouldBindJSON(&user); err != nil { 25 | c.JSON(http.StatusBadRequest, "Erro ao converter dados") 26 | return 27 | } 28 | 29 | validate := validator.New() 30 | err := validate.Struct(user) 31 | 32 | if err != nil { 33 | fmt.Println(err) 34 | c.JSON(http.StatusBadRequest, "Erro ao validar dados") 35 | return 36 | } 37 | 38 | c.JSON(http.StatusOK, user) 39 | return 40 | }) 41 | 42 | r.Run() // listen and serve on 0.0.0.0:8080 (for windows "localhost:8080") 43 | } 44 | -------------------------------------------------------------------------------- /error_handling/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/HunCoding/golang-basics/error_handling 2 | 3 | go 1.18 4 | 5 | require ( 6 | github.com/gin-contrib/sse v0.1.0 // indirect 7 | github.com/gin-gonic/gin v1.7.7 // indirect 8 | github.com/go-playground/locales v0.13.0 // indirect 9 | github.com/go-playground/universal-translator v0.17.0 // indirect 10 | github.com/go-playground/validator/v10 v10.4.1 // indirect 11 | github.com/golang/protobuf v1.3.3 // indirect 12 | github.com/json-iterator/go v1.1.9 // indirect 13 | github.com/leodido/go-urn v1.2.0 // indirect 14 | github.com/mattn/go-isatty v0.0.12 // indirect 15 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect 16 | github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 // indirect 17 | github.com/ugorji/go/codec v1.1.7 // indirect 18 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 // indirect 19 | golang.org/x/sys v0.0.0-20200116001909-b77594299b42 // indirect 20 | gopkg.in/yaml.v2 v2.2.8 // indirect 21 | ) 22 | -------------------------------------------------------------------------------- /fundamentos-3/funcoes/passando-varios-valores-por-parametro/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | 7 | receivingStringParameters("TEST", "TEST", "TEST") 8 | 9 | funcaoTest := func() { 10 | fmt.Println("TEST DE DENTRO DA FUNCAO") 11 | } 12 | 13 | receivingFunctionParameters(funcaoTest, funcaoTest) 14 | 15 | funcaoTestWithParameters := func(valueString string, valueInt int) { 16 | fmt.Println(valueInt, valueString) 17 | } 18 | 19 | receivingFunctionWithParameterByParameters(funcaoTestWithParameters, funcaoTestWithParameters) 20 | 21 | } 22 | 23 | func receivingStringParameters(stringsValues ...string) { 24 | for _, x := range stringsValues { 25 | fmt.Println(x) 26 | } 27 | } 28 | 29 | func receivingFunctionParameters(stringsValues ...func()) { 30 | for _, x := range stringsValues { 31 | x() 32 | } 33 | } 34 | 35 | func receivingFunctionWithParameterByParameters(stringsValues ...func(string, int)) { 36 | for _, x := range stringsValues { 37 | x("TEST", 300) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /go1_19/flagTextVar.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "errors" 5 | "flag" 6 | "fmt" 7 | "strings" 8 | ) 9 | 10 | type Pessoa struct { 11 | Nome string 12 | Sobrenome string 13 | } 14 | 15 | func (p *Pessoa) MarshalText() ([]byte, error) { 16 | nomeCompleto := fmt.Sprintf("%s %s", p.Nome, p.Sobrenome) 17 | return []byte(nomeCompleto), nil 18 | } 19 | 20 | func (p *Pessoa) UnmarshalText(text []byte) error { 21 | if len(text) == 0 { 22 | return nil 23 | } 24 | 25 | s := string(text) 26 | parts := strings.Split(s, " ") 27 | 28 | if len(parts) < 2 { 29 | return errors.New("por favor, especifique primeiro e ultimo nome") 30 | } 31 | 32 | *p = Pessoa{ 33 | Nome: parts[0], 34 | Sobrenome: parts[1], 35 | } 36 | return nil 37 | } 38 | 39 | func main() { 40 | var p Pessoa 41 | 42 | valorPadrao := &Pessoa{ 43 | Nome: "Hun", 44 | Sobrenome: "Coding", 45 | } 46 | 47 | flag.TextVar(&p, "pessoa", valorPadrao, "Insira nome e sobrenome desejado") 48 | flag.Parse() 49 | fmt.Println(p) 50 | } 51 | -------------------------------------------------------------------------------- /minha-primeira-api/gin-gonic/go.mod: -------------------------------------------------------------------------------- 1 | module minha-primeira-api/gin-gonic 2 | 3 | go 1.18 4 | 5 | require github.com/gin-gonic/gin v1.7.7 6 | 7 | require ( 8 | github.com/gin-contrib/sse v0.1.0 // indirect 9 | github.com/go-playground/locales v0.13.0 // indirect 10 | github.com/go-playground/universal-translator v0.17.0 // indirect 11 | github.com/go-playground/validator/v10 v10.4.1 // indirect 12 | github.com/golang/protobuf v1.3.3 // indirect 13 | github.com/json-iterator/go v1.1.9 // indirect 14 | github.com/leodido/go-urn v1.2.0 // indirect 15 | github.com/mattn/go-isatty v0.0.12 // indirect 16 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect 17 | github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 // indirect 18 | github.com/stretchr/testify v1.7.1 // indirect 19 | github.com/ugorji/go/codec v1.1.7 // indirect 20 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 // indirect 21 | golang.org/x/sys v0.0.0-20200116001909-b77594299b42 // indirect 22 | gopkg.in/yaml.v2 v2.2.8 // indirect 23 | ) 24 | -------------------------------------------------------------------------------- /error_handling/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | type ErrorTest struct { 8 | Code int 9 | Message string 10 | } 11 | 12 | func (e ErrorTest) Error() string { 13 | return fmt.Sprintf("Erro ao processar dados, code=%d, message=%s", 14 | e.Code, 15 | e.Message, 16 | ) 17 | } 18 | 19 | type TestStruct struct { 20 | Code int `json:"code"` 21 | Name string `json:"name"` 22 | FullName string `json:"full_name"` 23 | Age int `json:"age"` 24 | Adress Adress `json:"adress"` 25 | PhoneNumber string `json:"phone_number"` 26 | } 27 | 28 | type Adress struct { 29 | Street int `json:"street"` 30 | Number int `json:"number"` 31 | City string `json:"city"` 32 | State string `json:"state"` 33 | Country string `json:"country"` 34 | } 35 | 36 | func main() { 37 | if err := test(); err != nil { 38 | fmt.Printf("%#v", err) 39 | } 40 | } 41 | 42 | func test() *ErrorTest { 43 | err := &ErrorTest{ 44 | Code: 500, 45 | Message: "Deu erro aqui", 46 | } 47 | 48 | return err 49 | } 50 | -------------------------------------------------------------------------------- /minha-primeira-api/validando-dados/go.mod: -------------------------------------------------------------------------------- 1 | module huncoding/minha-primeira-api/validando-dados 2 | 3 | go 1.18 4 | 5 | require ( 6 | github.com/gin-contrib/sse v0.1.0 // indirect 7 | github.com/gin-gonic/gin v1.7.7 8 | github.com/go-playground/locales v0.14.0 // indirect 9 | github.com/go-playground/universal-translator v0.18.0 // indirect 10 | github.com/go-playground/validator/v10 v10.10.0 // indirect 11 | github.com/golang/protobuf v1.5.2 // indirect 12 | github.com/json-iterator/go v1.1.12 // indirect 13 | github.com/leodido/go-urn v1.2.1 // indirect 14 | github.com/mattn/go-isatty v0.0.14 // indirect 15 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 16 | github.com/modern-go/reflect2 v1.0.2 // indirect 17 | github.com/ugorji/go/codec v1.2.6 // indirect 18 | golang.org/x/crypto v0.0.0-20220214200702-86341886e292 // indirect 19 | golang.org/x/sys v0.0.0-20220224120231-95c6836cb0e7 // indirect 20 | golang.org/x/text v0.3.7 // indirect 21 | google.golang.org/protobuf v1.27.1 // indirect 22 | gopkg.in/yaml.v2 v2.4.0 // indirect 23 | ) 24 | -------------------------------------------------------------------------------- /templateCode/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "os" 5 | "text/template" 6 | ) 7 | 8 | func main() { 9 | templ := `package {{.Package}} 10 | 11 | import "fmt" 12 | 13 | type {{.StructName}} struct { 14 | {{range .Fields}} {{.Name}} {{.Type}} 15 | {{end}} 16 | } 17 | 18 | func printStruct(s {{.StructName}}) { 19 | fmt.Println(s) 20 | } 21 | 22 | func main() { 23 | s := {{.StructName}}{ 24 | {{range .Fields}} {{.Name}}: {{.Value}}, 25 | {{end}} 26 | } 27 | 28 | printStruct(s) 29 | } 30 | ` 31 | 32 | type Field struct { 33 | Name string 34 | Type string 35 | Value string 36 | } 37 | 38 | type Model struct { 39 | Package string 40 | StructName string 41 | Fields []Field 42 | } 43 | 44 | data := Model{ 45 | Package: "main", 46 | StructName: "Person", 47 | Fields: []Field{ 48 | {Name: "Name", Type: "string", Value: `"John"`}, 49 | {Name: "Youtube", Type: "string", Value: `"youtube.com/@huncoding"`}, 50 | }, 51 | } 52 | 53 | t := template.Must(template.New("main").Parse(templ)) 54 | t.Execute(os.Stdout, data) 55 | } 56 | -------------------------------------------------------------------------------- /live-reload/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/HunCoding/golang-basics/live-reload 2 | 3 | go 1.19 4 | 5 | require github.com/gin-gonic/gin v1.8.2 6 | 7 | require ( 8 | github.com/gin-contrib/sse v0.1.0 // indirect 9 | github.com/go-playground/locales v0.14.0 // indirect 10 | github.com/go-playground/universal-translator v0.18.0 // indirect 11 | github.com/go-playground/validator/v10 v10.11.1 // indirect 12 | github.com/goccy/go-json v0.9.11 // indirect 13 | github.com/json-iterator/go v1.1.12 // indirect 14 | github.com/leodido/go-urn v1.2.1 // indirect 15 | github.com/mattn/go-isatty v0.0.17 // indirect 16 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect 17 | github.com/modern-go/reflect2 v1.0.2 // indirect 18 | github.com/pelletier/go-toml/v2 v2.0.6 // indirect 19 | github.com/ugorji/go/codec v1.2.7 // indirect 20 | golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 // indirect 21 | golang.org/x/net v0.4.0 // indirect 22 | golang.org/x/sys v0.4.0 // indirect 23 | golang.org/x/text v0.5.0 // indirect 24 | google.golang.org/protobuf v1.28.1 // indirect 25 | gopkg.in/yaml.v2 v2.4.0 // indirect 26 | ) 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 HunCoding 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 | -------------------------------------------------------------------------------- /bad-things/go.mod: -------------------------------------------------------------------------------- 1 | module bad-things 2 | 3 | go 1.19 4 | 5 | require github.com/gin-gonic/gin v1.8.1 6 | 7 | require ( 8 | github.com/gin-contrib/sse v0.1.0 // indirect 9 | github.com/go-playground/locales v0.14.0 // indirect 10 | github.com/go-playground/universal-translator v0.18.0 // indirect 11 | github.com/go-playground/validator/v10 v10.10.0 // indirect 12 | github.com/goccy/go-json v0.9.7 // indirect 13 | github.com/json-iterator/go v1.1.12 // indirect 14 | github.com/leodido/go-urn v1.2.1 // indirect 15 | github.com/mattn/go-isatty v0.0.14 // indirect 16 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect 17 | github.com/modern-go/reflect2 v1.0.2 // indirect 18 | github.com/pelletier/go-toml/v2 v2.0.1 // indirect 19 | github.com/ugorji/go/codec v1.2.7 // indirect 20 | golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 // indirect 21 | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 // indirect 22 | golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069 // indirect 23 | golang.org/x/text v0.3.6 // indirect 24 | google.golang.org/protobuf v1.28.0 // indirect 25 | gopkg.in/yaml.v2 v2.4.0 // indirect 26 | ) 27 | -------------------------------------------------------------------------------- /test-containers/test_container.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "github.com/ory/dockertest" 7 | "go.mongodb.org/mongo-driver/mongo" 8 | "go.mongodb.org/mongo-driver/mongo/options" 9 | "log" 10 | ) 11 | 12 | func OpenConnection() (close func()) { 13 | pool, err := dockertest.NewPool("") 14 | if err != nil { 15 | log.Fatalf("Could not construct pool: %s", err) 16 | return 17 | } 18 | 19 | resource, err := pool.RunWithOptions(&dockertest.RunOptions{ 20 | Repository: "mongo", 21 | Tag: "latest", 22 | }) 23 | if err != nil { 24 | log.Fatalf("Could not create mongo container: %s", err) 25 | return 26 | } 27 | 28 | client, err := mongo.NewClient(options.Client().ApplyURI( 29 | fmt.Sprintf("mongodb://127.0.0.1:%s", resource.GetPort("27017/tcp")))) 30 | if err != nil { 31 | log.Println("Error trying to open connection") 32 | return 33 | } 34 | 35 | err = client.Connect(context.Background()) 36 | if err != nil { 37 | log.Println("Error trying to open connection") 38 | return 39 | } 40 | 41 | Collection = client.Database(DatabaseName).Collection(CollectionName) 42 | close = func() { 43 | err := resource.Close() 44 | if err != nil { 45 | log.Println("Error trying to open connection") 46 | return 47 | } 48 | } 49 | 50 | return 51 | } 52 | -------------------------------------------------------------------------------- /bad-things/errorHandling.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | ) 7 | 8 | var Func1Err = errors.New("error from Func1") 9 | var Func2Err = errors.New("error from Func2") 10 | var Func3Err = errors.New("error from Func3") 11 | 12 | func testeError() (int, error) { 13 | 14 | _, err := Func1() 15 | if err != nil { 16 | switch { 17 | case errors.Is(err, Func1Err): 18 | fmt.Println("error from expected function called") 19 | default: 20 | fmt.Printf("unexpected error: %s\n", err) 21 | } 22 | } 23 | 24 | _, err = Func2() 25 | if err != nil { 26 | switch { 27 | case errors.Is(err, Func2Err): 28 | fmt.Println("error from expected function called") 29 | default: 30 | fmt.Printf("unexpected error: %s\n", err) 31 | } 32 | } 33 | 34 | _, err = Func3() 35 | if err != nil { 36 | switch { 37 | case errors.Is(err, Func3Err): 38 | fmt.Println("error from expected function called") 39 | default: 40 | fmt.Printf("unexpected error: %s\n", err) 41 | } 42 | } 43 | 44 | return 1, nil 45 | } 46 | 47 | func Func1() (int, error) { 48 | return 1, errors.New("error from Func1") 49 | } 50 | 51 | func Func2() (int, error) { 52 | return 1, errors.New("error from Func2") 53 | } 54 | 55 | func Func3() (int, error) { 56 | return 1, errors.New("error from Func3") 57 | } 58 | -------------------------------------------------------------------------------- /test-containers/connect.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "go.mongodb.org/mongo-driver/bson" 7 | "go.mongodb.org/mongo-driver/bson/primitive" 8 | "go.mongodb.org/mongo-driver/mongo" 9 | "go.mongodb.org/mongo-driver/mongo/options" 10 | "log" 11 | ) 12 | 13 | var ( 14 | Collection *mongo.Collection 15 | CollectionName string = "testUserCol" 16 | DatabaseName string = "testUserDb" 17 | ) 18 | 19 | func main() { 20 | client, err := mongo.NewClient(options.Client().ApplyURI("mongodb://127.0.0.1:27017")) 21 | if err != nil { 22 | log.Println("Error trying to open connection") 23 | return 24 | } 25 | 26 | err = client.Connect(context.Background()) 27 | if err != nil { 28 | log.Println("Error trying to open connection") 29 | return 30 | } 31 | 32 | Collection = client.Database(DatabaseName).Collection(CollectionName) 33 | 34 | user, err := CreateUser("Huncoding") 35 | fmt.Println(user) 36 | } 37 | 38 | type User struct { 39 | ID string `bson:"_id"` 40 | Name string `bson:"name"` 41 | } 42 | 43 | func CreateUser( 44 | name string, 45 | ) (*User, error) { 46 | user := bson.M{"name": name} 47 | result, err := Collection.InsertOne(context.Background(), user) 48 | if err != nil { 49 | return nil, err 50 | } 51 | 52 | userObj := &User{ 53 | Name: name, 54 | } 55 | 56 | userObj.ID = result.InsertedID.(primitive.ObjectID).Hex() 57 | 58 | return userObj, nil 59 | } 60 | -------------------------------------------------------------------------------- /bancos-de-dados/mysql/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "database/sql" 5 | "fmt" 6 | 7 | _ "github.com/go-sql-driver/mysql" 8 | ) 9 | 10 | var ( 11 | db *sql.DB 12 | ) 13 | 14 | type User struct { 15 | Name string 16 | Age int 17 | } 18 | 19 | func main() { 20 | 21 | var err error 22 | 23 | db, err = sql.Open("mysql", "root:test123@tcp(172.17.0.2:3306)/users_db") 24 | if err != nil { 25 | panic(err) 26 | } 27 | 28 | user := User{ 29 | Name: "HunCoding 2", 30 | Age: 50, 31 | } 32 | 33 | if insertError := insertUser(user); insertError != nil { 34 | panic(err) 35 | } 36 | 37 | users, err := getAllUsers() 38 | if err != nil { 39 | panic(err) 40 | } 41 | 42 | for _, user := range users { 43 | fmt.Println(*user) 44 | } 45 | } 46 | 47 | func getAllUsers() ([]*User, error) { 48 | res, err := db.Query("SELECT * FROM user_data") 49 | if err != nil { 50 | return nil, err 51 | } 52 | 53 | users := []*User{} 54 | 55 | for res.Next() { 56 | 57 | var user User 58 | 59 | if err := res.Scan(&user.Name, &user.Age); err != nil { 60 | return nil, err 61 | } 62 | 63 | users = append(users, &user) 64 | } 65 | 66 | return users, nil 67 | } 68 | 69 | func insertUser(user User) error { 70 | _, err := db.Exec(fmt.Sprintf("INSERT INTO user_data VALUES('%s', %d)", user.Name, user.Age)) 71 | if err != nil { 72 | return err 73 | } 74 | 75 | fmt.Println("Usuario inserido com sucesso") 76 | return nil 77 | } 78 | -------------------------------------------------------------------------------- /consensus/cmd/server/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "log" 6 | "os" 7 | "os/signal" 8 | "strings" 9 | "syscall" 10 | 11 | "consensus/pkg/api" 12 | "consensus/pkg/raft" 13 | "consensus/pkg/store" 14 | ) 15 | 16 | func main() { 17 | // Parse command line flags 18 | nodeID := flag.String("id", "", "Node ID") 19 | httpAddr := flag.String("http", ":8080", "HTTP server address") 20 | rpcAddr := flag.String("rpc", ":9090", "RPC server address") 21 | peers := flag.String("peers", "", "Comma-separated list of peer addresses") 22 | flag.Parse() 23 | 24 | if *nodeID == "" { 25 | log.Fatal("Node ID is required") 26 | } 27 | 28 | // Create Raft node 29 | config := raft.DefaultConfig() 30 | config.ID = *nodeID 31 | 32 | // Parse peers 33 | if *peers != "" { 34 | config.Peers = strings.Split(*peers, ",") 35 | } 36 | 37 | raftNode := raft.NewNode(config) 38 | 39 | // Start RPC server 40 | if err := raftNode.StartRPCServer(*rpcAddr); err != nil { 41 | log.Fatal(err) 42 | } 43 | 44 | raftNode.Start() 45 | 46 | // Create distributed store 47 | store := store.NewStore(raftNode) 48 | 49 | // Create and start HTTP server 50 | server := api.NewServer(store, raftNode) 51 | go func() { 52 | if err := server.Start(*httpAddr); err != nil { 53 | log.Fatal(err) 54 | } 55 | }() 56 | 57 | // Wait for interrupt signal 58 | sigCh := make(chan os.Signal, 1) 59 | signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM) 60 | <-sigCh 61 | 62 | // Cleanup 63 | raftNode.Stop() 64 | } 65 | -------------------------------------------------------------------------------- /errgroup/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "golang.org/x/sync/errgroup" 7 | "math/rand" 8 | "sync" 9 | "time" 10 | ) 11 | 12 | func processTask(id int) error { 13 | delay := time.Duration(rand.Intn(1000)) * time.Millisecond 14 | time.Sleep(delay) 15 | 16 | if rand.Float32() < 0.2 { 17 | return fmt.Errorf("erro ao processar tarefa %d", id) 18 | } 19 | fmt.Printf("Tarefa %d concluída em %v\n", id, delay) 20 | return nil 21 | } 22 | 23 | func main() { 24 | ctx, cancel := context.WithCancel(context.Background()) 25 | defer cancel() 26 | 27 | maxConcurrency := 5 28 | semaphore := make(chan struct{}, maxConcurrency) 29 | 30 | var g errgroup.Group 31 | var mu sync.Mutex 32 | totalTasks := 20 33 | completedTasks := 0 34 | 35 | for i := 1; i <= totalTasks; i++ { 36 | i := i 37 | g.Go(func() error { 38 | semaphore <- struct{}{} 39 | defer func() { <-semaphore }() 40 | 41 | select { 42 | case <-ctx.Done(): 43 | return ctx.Err() 44 | default: 45 | if err := processTask(i); err != nil { 46 | cancel() 47 | return err 48 | } 49 | 50 | mu.Lock() 51 | completedTasks++ 52 | mu.Unlock() 53 | 54 | return nil 55 | } 56 | }) 57 | } 58 | 59 | if err := g.Wait(); err != nil { 60 | fmt.Printf("Processamento interrompido devido a erro: %v\n", err) 61 | } else { 62 | fmt.Println("Todas as tarefas foram concluídas com sucesso.") 63 | } 64 | 65 | fmt.Printf("Total de tarefas concluídas: %d/%d\n", completedTasks, totalTasks) 66 | } 67 | -------------------------------------------------------------------------------- /websocket_chat_app/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/gorilla/websocket" 5 | "log" 6 | "net/http" 7 | ) 8 | 9 | var upgrader = websocket.Upgrader{ 10 | ReadBufferSize: 1024, 11 | WriteBufferSize: 1024, 12 | } 13 | 14 | var clients = make(map[*websocket.Conn]bool) 15 | var broadcast = make(chan Message) 16 | 17 | type Message struct { 18 | Username string `json:"username"` 19 | Message string `json:"message"` 20 | } 21 | 22 | func main() { 23 | fs := http.FileServer(http.Dir(".")) 24 | http.Handle("/", fs) 25 | 26 | http.HandleFunc("/ws", handleConnections) 27 | 28 | go handleMessages() 29 | 30 | log.Println("HTTP server started on :8080") 31 | err := http.ListenAndServe(":8080", nil) 32 | if err != nil { 33 | log.Fatal("ListenAndServe: ", err) 34 | } 35 | } 36 | 37 | func handleConnections(w http.ResponseWriter, r *http.Request) { 38 | ws, err := upgrader.Upgrade(w, r, nil) 39 | if err != nil { 40 | log.Fatal(err) 41 | } 42 | defer ws.Close() 43 | 44 | clients[ws] = true 45 | 46 | for { 47 | var msg Message 48 | err := ws.ReadJSON(&msg) 49 | if err != nil { 50 | log.Printf("error: %v", err) 51 | delete(clients, ws) 52 | break 53 | } 54 | broadcast <- msg 55 | } 56 | } 57 | 58 | func handleMessages() { 59 | for { 60 | msg := <-broadcast 61 | for client := range clients { 62 | err := client.WriteJSON(msg) 63 | if err != nil { 64 | log.Printf("error: %v", err) 65 | client.Close() 66 | delete(clients, client) 67 | } 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /calling-chatgpt-api/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "encoding/json" 6 | "fmt" 7 | "io/ioutil" 8 | "net/http" 9 | ) 10 | 11 | func main() { 12 | // Preencha com o seu API key 13 | apiKey := "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" 14 | 15 | // Dados da mensagem para o ChatGPT 16 | input := "Canal do Youtube HunCoding" 17 | 18 | // Constrói a requisição HTTP POST 19 | requestBody, err := json.Marshal(map[string]interface{}{ 20 | "model": "text-davinci-003", 21 | "prompt": input, 22 | "max_tokens": 4000, 23 | "temperature": 1.0, 24 | }) 25 | if err != nil { 26 | fmt.Println("Erro ao construir corpo da requisição: ", err.Error()) 27 | return 28 | } 29 | 30 | req, err := http.NewRequest("POST", "https://api.openai.com/v1/completions", bytes.NewBuffer(requestBody)) 31 | if err != nil { 32 | fmt.Println("Erro ao criar requisição: ", err.Error()) 33 | return 34 | } 35 | req.Header.Set("Content-Type", "application/json") 36 | req.Header.Set("Authorization", "Bearer "+apiKey) 37 | 38 | // Executa a requisição 39 | client := &http.Client{} 40 | resp, err := client.Do(req) 41 | if err != nil { 42 | fmt.Println("Erro ao executar requisição: ", err.Error()) 43 | return 44 | } 45 | defer resp.Body.Close() 46 | 47 | // Lê a resposta 48 | body, err := ioutil.ReadAll(resp.Body) 49 | if err != nil { 50 | fmt.Println("Erro ao ler resposta: ", err.Error()) 51 | return 52 | } 53 | 54 | // Exibe a resposta em formato JSON 55 | fmt.Println(string(body)) 56 | } 57 | -------------------------------------------------------------------------------- /circuitBreak/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "math/rand" 7 | "time" 8 | 9 | "github.com/sony/gobreaker" 10 | ) 11 | 12 | func mockService() (string, error) { 13 | if rand.Intn(100) > 90 { 14 | return "success", nil 15 | } 16 | 17 | return "", errors.New("error trying to process request") 18 | } 19 | 20 | func logState(name string, from gobreaker.State, to gobreaker.State) { 21 | fmt.Printf("%s: State change: %s -> %s\n", name, stateToString(from), stateToString(to)) 22 | } 23 | 24 | func stateToString(state gobreaker.State) string { 25 | switch state { 26 | case gobreaker.StateClosed: 27 | return "Closed" 28 | case gobreaker.StateHalfOpen: 29 | return "Half-Open" 30 | case gobreaker.StateOpen: 31 | return "Open" 32 | default: 33 | return "Unknown" 34 | } 35 | } 36 | 37 | func main() { 38 | settings := gobreaker.Settings{ 39 | Name: "MyCircuitBreakerService", 40 | MaxRequests: 3, 41 | Interval: 5 * time.Second, 42 | Timeout: 5 * time.Second, 43 | ReadyToTrip: func(counts gobreaker.Counts) bool { 44 | return counts.ConsecutiveFailures > 2 45 | }, 46 | OnStateChange: logState, 47 | } 48 | 49 | cb := gobreaker.NewCircuitBreaker(settings) 50 | 51 | for i := 0; i < 10; i++ { 52 | _, err := cb.Execute(func() (interface{}, error) { 53 | return mockService() 54 | }) 55 | 56 | if err != nil { 57 | fmt.Println(err.Error()) 58 | } else { 59 | fmt.Println("Circuit Breaker: Success") 60 | } 61 | 62 | time.Sleep(1 * time.Second) 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /consensus/pkg/raft/types.go: -------------------------------------------------------------------------------- 1 | package raft 2 | 3 | import ( 4 | "time" 5 | ) 6 | 7 | // NodeState represents the current state of a Raft node 8 | type NodeState int 9 | 10 | const ( 11 | Follower NodeState = iota 12 | Candidate 13 | Leader 14 | ) 15 | 16 | // LogEntry represents a single entry in the Raft log 17 | type LogEntry struct { 18 | Term int 19 | Command interface{} 20 | } 21 | 22 | // RequestVoteArgs represents the arguments for RequestVote RPC 23 | type RequestVoteArgs struct { 24 | Term int 25 | CandidateID string 26 | LastLogIndex int 27 | LastLogTerm int 28 | } 29 | 30 | // RequestVoteReply represents the reply for RequestVote RPC 31 | type RequestVoteReply struct { 32 | Term int 33 | VoteGranted bool 34 | } 35 | 36 | // AppendEntriesArgs represents the arguments for AppendEntries RPC 37 | type AppendEntriesArgs struct { 38 | Term int 39 | LeaderID string 40 | PrevLogIndex int 41 | PrevLogTerm int 42 | Entries []LogEntry 43 | LeaderCommit int 44 | } 45 | 46 | // AppendEntriesReply represents the reply for AppendEntries RPC 47 | type AppendEntriesReply struct { 48 | Term int 49 | Success bool 50 | } 51 | 52 | // Config holds the configuration for a Raft node 53 | type Config struct { 54 | ID string 55 | Peers []string 56 | ElectionTimeout time.Duration 57 | HeartbeatInterval time.Duration 58 | } 59 | 60 | // DefaultConfig returns a default configuration 61 | func DefaultConfig() *Config { 62 | return &Config{ 63 | ElectionTimeout: time.Millisecond * 300, 64 | HeartbeatInterval: time.Millisecond * 100, 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /websocket_chat_app/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Chat App 7 | 20 | 21 | 22 |
    23 |
    24 | 25 | 26 | 27 |
    28 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /fuzz/contains_test.go: -------------------------------------------------------------------------------- 1 | package fuzz 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | "testing" 7 | ) 8 | 9 | func TestMyIndexAny(t *testing.T) { 10 | tests := []struct { 11 | s, chars string 12 | want int 13 | }{ 14 | {"", "", -1}, 15 | {"", "a", -1}, 16 | {"", "abc", -1}, 17 | {"a", "", -1}, 18 | {"a", "a", 0}, 19 | {"abc", "xyz", -1}, 20 | {"abc", "xcz", 2}, 21 | {"abøc", "xøyz", 2}, 22 | {"a\x20c", "xyz\x20", 1}, 23 | {"\x00\x01\x02", "\x00", 0}, 24 | {"\x70\x71\x72", "\x73", -1}, 25 | {"sRegExp*", ".(|)*+?^$[]", 7}, 26 | } 27 | 28 | for _, test := range tests { 29 | t.Run(fmt.Sprintf("(%q, %q)", test.s, test.chars), func(t *testing.T) { 30 | if got := MyIndexAny(test.s, test.chars); got != test.want { 31 | t.Errorf("%d, want %d", got, test.want) 32 | } 33 | }) 34 | } 35 | } 36 | 37 | func FuzzMyIndexAny(f *testing.F) { 38 | tests := []struct { 39 | s, chars string 40 | want int 41 | }{ 42 | {"", "", -1}, 43 | {"", "a", -1}, 44 | {"", "abc", -1}, 45 | {"a", "", -1}, 46 | {"a", "a", 0}, 47 | {"abc", "xyz", -1}, 48 | {"abc", "xcz", 2}, 49 | {"abøc", "xøyz", 2}, 50 | {"a\x20c", "xyz\x20", 1}, 51 | {"\x00\x01\x02", "\x00", 0}, 52 | {"\x70\x71\x72", "\x73", -1}, 53 | {"sRegExp*", ".(|)*+?^$[]", 7}, 54 | {"sRegExp*", ".(|)*+?^$[]", 7}, 55 | } 56 | for _, test := range tests { 57 | f.Add(test.s, test.chars) 58 | } 59 | 60 | f.Fuzz(func(t *testing.T, s, chars string) { 61 | if want, got := MyIndexAny(s, chars), strings.IndexAny(s, chars); got != want { 62 | t.Errorf("(%q, %q), MyIndex=%d, strings.IndexAny=%d", 63 | s, chars, want, got) 64 | } 65 | }) 66 | } 67 | -------------------------------------------------------------------------------- /stateMachine/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | const ( 6 | StateOpen = "open" 7 | StateClose = "close" 8 | StateLocked = "locked" 9 | ) 10 | 11 | const ( 12 | EventOpen = "open" 13 | EventClose = "close" 14 | EventLock = "lock" 15 | EventUnlock = "unlock" 16 | ) 17 | 18 | type StateMachine struct { 19 | state string 20 | transitions map[string]map[string]string 21 | } 22 | 23 | func NewStateMachine( 24 | initialState string, 25 | transitions map[string]map[string]string) *StateMachine { 26 | return &StateMachine{ 27 | state: initialState, 28 | transitions: transitions, 29 | } 30 | } 31 | 32 | func (sm *StateMachine) State() string { 33 | return sm.state 34 | } 35 | 36 | func (sm *StateMachine) Trigger(event string) error { 37 | if nextStep, ok := sm.transitions[sm.state][event]; ok { 38 | fmt.Println("Transitioning from", sm.state, "to", nextStep, "for event", event) 39 | sm.state = nextStep 40 | return nil 41 | } 42 | 43 | return fmt.Errorf("Invalid event %s for current state %s", event, sm.state) 44 | } 45 | 46 | func main() { 47 | transition := map[string]map[string]string{ 48 | StateOpen: { 49 | EventClose: StateClose, 50 | EventLock: StateLocked, 51 | }, 52 | StateClose: { 53 | EventOpen: StateOpen, 54 | }, 55 | StateLocked: { 56 | EventUnlock: StateClose, 57 | }, 58 | } 59 | 60 | sm := NewStateMachine(StateOpen, transition) 61 | 62 | event := []string{EventOpen, EventOpen, EventLock, EventUnlock} 63 | for _, e := range event { 64 | err := sm.Trigger(e) 65 | if err != nil { 66 | fmt.Println(err) 67 | } 68 | } 69 | 70 | fmt.Println("Final state is", sm.State()) 71 | } 72 | -------------------------------------------------------------------------------- /bancos-de-dados/mongodb/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "log" 7 | 8 | "go.mongodb.org/mongo-driver/bson" 9 | "go.mongodb.org/mongo-driver/bson/primitive" 10 | "go.mongodb.org/mongo-driver/mongo" 11 | "go.mongodb.org/mongo-driver/mongo/options" 12 | ) 13 | 14 | type User struct { 15 | ID primitive.ObjectID `bson:"_id,omitempty"` 16 | Name string `bson:"name"` 17 | Age int32 `bson:"age"` 18 | } 19 | 20 | func main() { 21 | client, err := mongo.Connect(context.Background(), options.Client().ApplyURI("mongodb://localhost:27017")) 22 | if err != nil { 23 | panic(err) 24 | } 25 | 26 | user := User{Name: "Huncoding", 27 | Age: 30, 28 | } 29 | 30 | collection := client.Database("user").Collection("userData") 31 | 32 | //INSERT ONE 33 | result, err := collection.InsertOne(context.Background(), user) 34 | if err != nil { 35 | panic(err) 36 | } 37 | 38 | fmt.Println(result.InsertedID) 39 | 40 | //FIND ONE 41 | filter := bson.D{{"name", user.Name}} 42 | userResult := User{} 43 | errFinding := collection.FindOne(context.Background(), filter).Decode(&userResult) 44 | if errFinding != nil { 45 | panic(errFinding) 46 | } 47 | 48 | fmt.Println(userResult) 49 | 50 | //FIND ALL 51 | cur, err := collection.Find(context.Background(), bson.D{}) 52 | if err != nil { 53 | log.Fatal(err) 54 | } 55 | defer cur.Close(context.Background()) 56 | for cur.Next(context.Background()) { 57 | // To decode into a struct, use cursor.Decode() 58 | userResult := User{} 59 | 60 | err := cur.Decode(&userResult) 61 | if err != nil { 62 | log.Fatal(err) 63 | } 64 | 65 | fmt.Println(userResult) 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /bancos-de-dados/cassandradb/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/gocql/gocql" 7 | ) 8 | 9 | var ( 10 | session *gocql.Session 11 | ) 12 | 13 | type User struct { 14 | ID string 15 | Name string 16 | Age int 17 | } 18 | 19 | func main() { 20 | 21 | var err error 22 | 23 | cluster := gocql.NewCluster("172.18.0.2") 24 | cluster.Keyspace = "users_keyspace" 25 | session, err = cluster.CreateSession() 26 | 27 | if err != nil { 28 | panic(err) 29 | } 30 | 31 | id, err := gocql.RandomUUID() 32 | if err != nil { 33 | panic(fmt.Sprintf("Error trying to generate a random uuid, error=%v", err)) 34 | } 35 | 36 | user := User{ 37 | ID: id.String(), 38 | Name: "Huncoding", 39 | Age: 30, 40 | } 41 | 42 | userInsertResult, err := insertUser(user) 43 | if err != nil { 44 | panic(err) 45 | } 46 | 47 | fmt.Printf("Inserted id: %v \n", userInsertResult) 48 | 49 | userGetResult, err := getUserById(user.ID) 50 | if err != nil { 51 | panic(err) 52 | } 53 | 54 | fmt.Printf("Resulted user: %v \n", userGetResult) 55 | 56 | } 57 | 58 | func insertUser(user User) (*User, error) { 59 | if err := session.Query( 60 | "INSERT INTO users(user_id, age, name) VALUES (?, ?, ?);", 61 | user.ID, 62 | user.Age, 63 | user.Name, 64 | ).Exec(); err != nil { 65 | return nil, err 66 | } 67 | 68 | return &user, nil 69 | } 70 | 71 | func getUserById(id string) (*User, error) { 72 | 73 | var user User 74 | 75 | if err := session.Query( 76 | "SELECT user_id, age, name FROM users WHERE user_id = ?", 77 | id).Scan( 78 | &user.ID, 79 | &user.Age, 80 | &user.Name, 81 | ); err != nil { 82 | return nil, err 83 | } 84 | 85 | return &user, nil 86 | } 87 | -------------------------------------------------------------------------------- /framework-performance-diff/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/HunCoding/golang-basics/framework-performance-diff 2 | 3 | go 1.19 4 | 5 | require ( 6 | github.com/gin-gonic/gin v1.8.1 7 | github.com/go-chi/chi/v5 v5.0.7 8 | github.com/gofiber/fiber/v2 v2.39.0 9 | github.com/gorilla/mux v1.8.0 10 | ) 11 | 12 | require ( 13 | github.com/andybalholm/brotli v1.0.4 // indirect 14 | github.com/gin-contrib/sse v0.1.0 // indirect 15 | github.com/go-playground/locales v0.14.0 // indirect 16 | github.com/go-playground/universal-translator v0.18.0 // indirect 17 | github.com/go-playground/validator/v10 v10.10.0 // indirect 18 | github.com/goccy/go-json v0.9.7 // indirect 19 | github.com/json-iterator/go v1.1.12 // indirect 20 | github.com/klauspost/compress v1.15.0 // indirect 21 | github.com/leodido/go-urn v1.2.1 // indirect 22 | github.com/mattn/go-colorable v0.1.13 // indirect 23 | github.com/mattn/go-isatty v0.0.16 // indirect 24 | github.com/mattn/go-runewidth v0.0.14 // indirect 25 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect 26 | github.com/modern-go/reflect2 v1.0.2 // indirect 27 | github.com/pelletier/go-toml/v2 v2.0.1 // indirect 28 | github.com/rivo/uniseg v0.2.0 // indirect 29 | github.com/ugorji/go/codec v1.2.7 // indirect 30 | github.com/valyala/bytebufferpool v1.0.0 // indirect 31 | github.com/valyala/fasthttp v1.40.0 // indirect 32 | github.com/valyala/tcplisten v1.0.0 // indirect 33 | golang.org/x/crypto v0.0.0-20220214200702-86341886e292 // indirect 34 | golang.org/x/net v0.0.0-20220225172249-27dd8689420f // indirect 35 | golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab // indirect 36 | golang.org/x/text v0.3.7 // indirect 37 | google.golang.org/protobuf v1.28.0 // indirect 38 | gopkg.in/yaml.v2 v2.4.0 // indirect 39 | ) 40 | -------------------------------------------------------------------------------- /watcher-files/watcher.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io/ioutil" 6 | "log" 7 | 8 | "github.com/fsnotify/fsnotify" 9 | yaml "gopkg.in/yaml.v2" 10 | ) 11 | 12 | var ( 13 | Configurations User 14 | ) 15 | 16 | type User struct { 17 | Username string `json:"username" yaml:"username"` 18 | Lastname string `json:"lastname" yaml:"lastname"` 19 | Age int8 `json:"age" yaml:"age"` 20 | } 21 | 22 | func ReadAndMarshalFile() { 23 | fmt.Println("Reading configuration") 24 | data, err := ioutil.ReadFile("configurations.yml") 25 | if err != nil { 26 | panic(err) 27 | } 28 | 29 | if err = yaml.Unmarshal([]byte(data), &Configurations); err != nil { 30 | panic(err) 31 | } 32 | 33 | fmt.Printf("Configuration loaded: %#v \n", Configurations) 34 | } 35 | 36 | func main() { 37 | watcher, err := fsnotify.NewWatcher() 38 | if err != nil { 39 | log.Fatal(err) 40 | } 41 | 42 | defer watcher.Close() 43 | done := make(chan bool) 44 | 45 | go func() { 46 | for { 47 | select { 48 | case event, ok := <-watcher.Events: 49 | if !ok { 50 | return 51 | } 52 | log.Println("event:", event) 53 | if event.Op&fsnotify.Write == fsnotify.Write { 54 | fmt.Println("File changed, changing configuration") 55 | ReadAndMarshalFile() 56 | fmt.Printf("New configuration: %#v\n", Configurations) 57 | } 58 | case err, ok := <-watcher.Errors: 59 | if !ok { 60 | return 61 | } 62 | log.Println("Error trying to load file, error:", err) 63 | } 64 | } 65 | }() 66 | 67 | //Adding listener to configuration file 68 | err = watcher.Add("configurations.yml") 69 | if err != nil { 70 | log.Fatal(err) 71 | } 72 | 73 | //Read and load configuration 74 | ReadAndMarshalFile() 75 | 76 | //Setting code to wait 77 | <-done 78 | } 79 | -------------------------------------------------------------------------------- /telemetry/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "go.opentelemetry.io/otel" 7 | "go.opentelemetry.io/otel/exporters/jaeger" 8 | "go.opentelemetry.io/otel/sdk/resource" 9 | "go.opentelemetry.io/otel/sdk/trace" 10 | semconv "go.opentelemetry.io/otel/semconv/v1.4.0" 11 | "log" 12 | "time" 13 | ) 14 | 15 | var tracer = otel.Tracer("Example-Go-Trace") 16 | 17 | func initTracer() func() { 18 | exporter, err := jaeger.New(jaeger.WithCollectorEndpoint( 19 | jaeger.WithEndpoint("http://localhost:14268/api/traces"))) 20 | if err != nil { 21 | log.Fatal(err) 22 | } 23 | 24 | resources := resource.NewWithAttributes( 25 | semconv.SchemaURL, 26 | semconv.ServiceNameKey.String("Example-Trace")) 27 | 28 | traceProvider := trace.NewTracerProvider( 29 | trace.WithBatcher(exporter), 30 | trace.WithResource(resources)) 31 | otel.SetTracerProvider(traceProvider) 32 | 33 | return func() { 34 | err := traceProvider.Shutdown(context.Background()) 35 | if err != nil { 36 | log.Fatal(err) 37 | } 38 | } 39 | } 40 | 41 | func main() { 42 | cleanup := initTracer() 43 | defer cleanup() 44 | 45 | ctx, span := tracer.Start(context.Background(), "main") 46 | defer span.End() 47 | 48 | doWork(ctx) 49 | } 50 | 51 | func doWork(ctx context.Context) { 52 | ctx, span := tracer.Start(ctx, "doWork") 53 | defer span.End() 54 | 55 | time.Sleep(100 * time.Millisecond) 56 | doSubWork(ctx) 57 | } 58 | 59 | func doSubWork(ctx context.Context) { 60 | ctx, span := tracer.Start(ctx, "doSubWork") 61 | defer span.End() 62 | 63 | time.Sleep(500 * time.Millisecond) 64 | doSubSubWork(ctx) 65 | } 66 | 67 | func doSubSubWork(ctx context.Context) { 68 | ctx, span := tracer.Start(ctx, "doSubSubWork") 69 | defer span.End() 70 | 71 | time.Sleep(1 * time.Second) 72 | 73 | fmt.Println("Codigo finalizado no ultimo metodo") 74 | } 75 | -------------------------------------------------------------------------------- /test-containers/go.mod: -------------------------------------------------------------------------------- 1 | module test-containers 2 | 3 | go 1.20 4 | 5 | require ( 6 | github.com/ory/dockertest v3.3.5+incompatible 7 | go.mongodb.org/mongo-driver v1.12.1 8 | ) 9 | 10 | require ( 11 | github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect 12 | github.com/Microsoft/go-winio v0.6.1 // indirect 13 | github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect 14 | github.com/cenkalti/backoff v2.2.1+incompatible // indirect 15 | github.com/containerd/continuity v0.4.2 // indirect 16 | github.com/docker/go-connections v0.4.0 // indirect 17 | github.com/docker/go-units v0.5.0 // indirect 18 | github.com/golang/snappy v0.0.1 // indirect 19 | github.com/gotestyourself/gotestyourself v2.2.0+incompatible // indirect 20 | github.com/klauspost/compress v1.13.6 // indirect 21 | github.com/lib/pq v1.10.9 // indirect 22 | github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe // indirect 23 | github.com/opencontainers/go-digest v1.0.0 // indirect 24 | github.com/opencontainers/image-spec v1.0.2 // indirect 25 | github.com/opencontainers/runc v1.1.9 // indirect 26 | github.com/pkg/errors v0.9.1 // indirect 27 | github.com/sirupsen/logrus v1.9.3 // indirect 28 | github.com/stretchr/testify v1.8.4 // indirect 29 | github.com/xdg-go/pbkdf2 v1.0.0 // indirect 30 | github.com/xdg-go/scram v1.1.2 // indirect 31 | github.com/xdg-go/stringprep v1.0.4 // indirect 32 | github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect 33 | golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d // indirect 34 | golang.org/x/mod v0.8.0 // indirect 35 | golang.org/x/net v0.8.0 // indirect 36 | golang.org/x/sync v0.1.0 // indirect 37 | golang.org/x/sys v0.6.0 // indirect 38 | golang.org/x/text v0.8.0 // indirect 39 | golang.org/x/tools v0.6.0 // indirect 40 | gotest.tools v2.2.0+incompatible // indirect 41 | ) 42 | -------------------------------------------------------------------------------- /exponentialBackoff/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | "fmt" 7 | "math/rand" 8 | "net/http" 9 | "time" 10 | ) 11 | 12 | func performRequest(ctx context.Context, url string) error { 13 | select { 14 | case <-ctx.Done(): 15 | return ctx.Err() 16 | default: 17 | if rand.Intn(3) != 0 { 18 | return errors.New("simulated request error") 19 | } 20 | resp, err := http.Get(url) 21 | if err != nil { 22 | return err 23 | } 24 | defer resp.Body.Close() 25 | fmt.Println("Request succeeded with status:", resp.StatusCode) 26 | return nil 27 | } 28 | } 29 | 30 | func retryWithContextBackoff(ctx context.Context, url string, maxRetries int, baseDelay time.Duration, maxTimeout time.Duration) error { 31 | retryDelay := baseDelay 32 | 33 | for attempt := 1; attempt <= maxRetries; attempt++ { 34 | err := performRequest(ctx, url) 35 | if err == nil { 36 | fmt.Printf("Request succeeded on attempt: %d\n", attempt) 37 | return nil 38 | } 39 | 40 | jitter := time.Duration(rand.Int63n(int64(retryDelay))) 41 | sleepTime := retryDelay + jitter/2 42 | fmt.Printf("Attempt %d failed: %s. Retrying in %s...\n", attempt, err, sleepTime) 43 | 44 | select { 45 | case <-time.After(sleepTime): 46 | retryDelay *= 2 47 | if retryDelay > maxTimeout { 48 | retryDelay = maxTimeout 49 | } 50 | case <-ctx.Done(): 51 | return fmt.Errorf("operation canceled: %w", ctx.Err()) 52 | } 53 | } 54 | return fmt.Errorf("max retries reached for URL: %s", url) 55 | } 56 | 57 | func main() { 58 | rand.Seed(time.Now().UnixNano()) 59 | url := "https://jsonplaceholder.typicode.com/posts/1" 60 | 61 | ctx, cancel := context.WithTimeout(context.Background(), time.Second*15) 62 | defer cancel() 63 | 64 | err := retryWithContextBackoff(ctx, url, 7, time.Millisecond*100, time.Second*2) 65 | if err != nil { 66 | fmt.Println("Operation failed:", err) 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /bancos-de-dados/cassandradb/go.sum: -------------------------------------------------------------------------------- 1 | github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932 h1:mXoPYz/Ul5HYEDvkta6I8/rnYM5gSdSV2tJ6XbZuEtY= 2 | github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCSz6Q9T7+igc/hlvDOUdtWKryOrtFyIVABv/p7k= 3 | github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY= 4 | github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= 5 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 6 | github.com/gocql/gocql v1.0.0 h1:UnbTERpP72VZ/viKE1Q1gPtmLvyTZTvuAstvSRydw/c= 7 | github.com/gocql/gocql v1.0.0/go.mod h1:3gM2c4D3AnkISwBxGnMMsS8Oy4y2lhbPRsH4xnJrHG8= 8 | github.com/golang/snappy v0.0.3 h1:fHPg5GQYlCeLIPB9BZqMVR5nR9A+IM5zcgeTdjMYmLA= 9 | github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= 10 | github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8= 11 | github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4= 12 | github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= 13 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= 14 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 15 | github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= 16 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= 17 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 18 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 19 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 20 | gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= 21 | gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= 22 | -------------------------------------------------------------------------------- /bancos-de-dados/elasticsearch/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "context" 6 | "encoding/json" 7 | "fmt" 8 | "io/ioutil" 9 | "math/rand" 10 | "strconv" 11 | 12 | "github.com/elastic/go-elasticsearch/esapi" 13 | "github.com/elastic/go-elasticsearch/v8" 14 | ) 15 | 16 | type User struct { 17 | ID string `json:"id,omitempty"` 18 | Name string `json:"name"` 19 | Age int16 `json:"age"` 20 | } 21 | 22 | var ( 23 | client *elasticsearch.Client 24 | ) 25 | 26 | func main() { 27 | 28 | cert, err := ioutil.ReadFile("/home/hunter/http_ca.crt") 29 | if err != nil { 30 | panic(err) 31 | } 32 | 33 | cfg := elasticsearch.Config{ 34 | Addresses: []string{ 35 | "https://localhost:9200", 36 | }, 37 | CACert: cert, 38 | Username: "elastic", 39 | Password: "lEUtD-LaqO2sZnTsLwrH", 40 | } 41 | 42 | client, err = elasticsearch.NewClient(cfg) 43 | if err != nil { 44 | panic(err) 45 | } 46 | 47 | _, err = client.Info() 48 | if err != nil { 49 | panic(err) 50 | } 51 | 52 | user := User{ 53 | Name: "HunCoding", 54 | Age: 30, 55 | } 56 | 57 | insertedId, err := Index(user) 58 | if err != nil { 59 | panic(err) 60 | } 61 | 62 | res, err := GetUser(insertedId) 63 | if err != nil { 64 | panic(err) 65 | } 66 | 67 | fmt.Println(res) 68 | } 69 | 70 | func Index(user User) (string, error) { 71 | 72 | id := rand.Intn(100) 73 | idUser := strconv.Itoa(id) 74 | 75 | requestBytes, err := json.Marshal(user) 76 | if err != nil { 77 | return "", err 78 | } 79 | 80 | cfg := esapi.IndexRequest{ 81 | DocumentID: idUser, 82 | Index: "users", 83 | Body: bytes.NewReader(requestBytes), 84 | Refresh: "true", 85 | } 86 | 87 | res, err := cfg.Do(context.Background(), client) 88 | if err != nil { 89 | return "", err 90 | } 91 | 92 | fmt.Println(res) 93 | 94 | return idUser, nil 95 | } 96 | 97 | func GetUser(id string) (*esapi.Response, error) { 98 | 99 | cfg := esapi.GetRequest{ 100 | Index: "users", 101 | DocumentID: id, 102 | } 103 | 104 | res, err := cfg.Do(context.Background(), client) 105 | if err != nil { 106 | return nil, err 107 | } 108 | 109 | return res, nil 110 | } 111 | -------------------------------------------------------------------------------- /rateLimit/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "net" 7 | "net/http" 8 | "sync" 9 | "time" 10 | 11 | "golang.org/x/time/rate" 12 | ) 13 | 14 | var ( 15 | visitors = make(map[string]*rate.Limiter) 16 | mu sync.Mutex 17 | ) 18 | 19 | func getIP(r *http.Request) string { 20 | ip, _, _ := net.SplitHostPort(r.RemoteAddr) 21 | return ip 22 | } 23 | 24 | func getVisitor(ip string) *rate.Limiter { 25 | mu.Lock() 26 | defer mu.Unlock() 27 | 28 | limiter, exists := visitors[ip] 29 | if !exists { 30 | limiter = rate.NewLimiter(1, 100) 31 | visitors[ip] = limiter 32 | } 33 | 34 | return limiter 35 | } 36 | 37 | func rateLimitByIP(h http.Handler) http.Handler { 38 | return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 39 | ip := getIP(r) 40 | limiter := getVisitor(ip) 41 | if !limiter.Allow() { 42 | log.Printf("[BLOCKED] Request was block using IP: %s\n", ip) 43 | http.Error(w, http.StatusText(429), http.StatusTooManyRequests) 44 | return 45 | } 46 | 47 | log.Printf("[ALLOWD] Request was allowd using IP: %s\n", ip) 48 | h.ServeHTTP(w, r) 49 | }) 50 | } 51 | 52 | func doRequestUsingDifferentIPs() { 53 | ips := []string{"192.168.1.1", "192.168.1.2", "192.168.1.3"} 54 | wg := sync.WaitGroup{} 55 | 56 | for _, ip := range ips { 57 | wg.Add(1) 58 | go func(ip string) { 59 | defer wg.Done() 60 | for i := 0; i < 10; i++ { 61 | sendRequest(ip) 62 | time.Sleep(300 * time.Millisecond) 63 | } 64 | }(ip) 65 | } 66 | 67 | wg.Wait() 68 | fmt.Println("Simulação concluída.") 69 | } 70 | 71 | func main() { 72 | mux := http.NewServeMux() 73 | 74 | mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { 75 | w.Write([]byte("Hello, World!")) 76 | }) 77 | 78 | go func() { 79 | http.ListenAndServe(":8080", rateLimitByIP(mux)) 80 | }() 81 | 82 | doRequestUsingDifferentIPs() 83 | } 84 | 85 | func sendRequest(ip string) { 86 | client := &http.Client{} 87 | req, _ := http.NewRequest("GET", "http://localhost:8080", nil) 88 | req.RemoteAddr = ip + ":12345" // Define o IP simulado 89 | resp, err := client.Do(req) 90 | if err != nil { 91 | log.Printf("[ERROR] Falha ao enviar requisição para IP %s: %v", ip, err) 92 | return 93 | } 94 | defer resp.Body.Close() 95 | 96 | log.Printf("[RESPONSE] IP: %s - Status: %s", ip, resp.Status) 97 | } 98 | -------------------------------------------------------------------------------- /b3TraceId/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "go.opentelemetry.io/contrib/propagators/b3" 7 | "go.opentelemetry.io/otel" 8 | "go.opentelemetry.io/otel/exporters/stdout/stdouttrace" 9 | "go.opentelemetry.io/otel/propagation" 10 | "go.opentelemetry.io/otel/sdk/resource" 11 | sdktrace "go.opentelemetry.io/otel/sdk/trace" 12 | semconv "go.opentelemetry.io/otel/semconv/v1.10.0" 13 | "log" 14 | "net/http" 15 | "time" 16 | ) 17 | 18 | var tracer = otel.Tracer("B3-Tracer") 19 | 20 | func initTracer() func() { 21 | exporter, err := stdouttrace.New(stdouttrace.WithPrettyPrint()) 22 | if err != nil { 23 | log.Fatal(err) 24 | } 25 | 26 | resources := resource.NewWithAttributes( 27 | semconv.SchemaURL, 28 | semconv.ServiceNameKey.String("Exemplo-B3-Trace"), 29 | ) 30 | 31 | tp := sdktrace.NewTracerProvider( 32 | sdktrace.WithBatcher(exporter), 33 | sdktrace.WithResource(resources), 34 | ) 35 | otel.SetTracerProvider(tp) 36 | 37 | otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(b3.New())) 38 | 39 | return func() { 40 | if err := tp.Shutdown(context.Background()); err != nil { 41 | log.Fatal(err) 42 | } 43 | } 44 | } 45 | 46 | func main() { 47 | cleanup := initTracer() 48 | defer cleanup() 49 | 50 | go func() { 51 | http.HandleFunc("/trace", func(w http.ResponseWriter, r *http.Request) { 52 | ctx := otel.GetTextMapPropagator().Extract( 53 | r.Context(), propagation.HeaderCarrier(r.Header)) 54 | 55 | ctx, span := tracer.Start(ctx, "ReceiveHandler") 56 | defer span.End() 57 | 58 | traceId := span.SpanContext().TraceID().String() 59 | fmt.Printf("TraceId gerado/recebido: %s \n", traceId) 60 | 61 | w.Header().Set("x-b3-traceid", traceId) 62 | w.Header().Set("b3-traceid", traceId) 63 | }) 64 | 65 | fmt.Println("Começando execução do endpoint") 66 | err := http.ListenAndServe("localhost:8080", nil) 67 | if err != nil { 68 | log.Fatal(err) 69 | } 70 | }() 71 | 72 | fmt.Print("Aguardando endpoint inicializar") 73 | time.Sleep(1 * time.Second) 74 | 75 | client := &http.Client{} 76 | ctx, span := tracer.Start(context.Background(), "ClientRequest") 77 | defer span.End() 78 | 79 | req, err := http.NewRequestWithContext(ctx, "GET", "http://localhost:8080/trace", nil) 80 | if err != nil { 81 | log.Fatal(err) 82 | } 83 | 84 | otel.GetTextMapPropagator().Inject(ctx, propagation.HeaderCarrier(req.Header)) 85 | 86 | resp, err := client.Do(req) 87 | if err != nil { 88 | log.Fatal(err) 89 | } 90 | 91 | defer resp.Body.Close() 92 | 93 | fmt.Printf("Resposta do servidor com header B3-TraceId: %s\n", resp.Header.Get("x-b3-traceid")) 94 | } 95 | -------------------------------------------------------------------------------- /consensus/pkg/store/store.go: -------------------------------------------------------------------------------- 1 | package store 2 | 3 | import ( 4 | "encoding/json" 5 | "errors" 6 | "sync" 7 | 8 | "consensus/pkg/raft" 9 | ) 10 | 11 | // Command represents a command to be executed on the store 12 | type Command struct { 13 | Op string `json:"op"` 14 | Key string `json:"key"` 15 | Value interface{} `json:"value"` 16 | } 17 | 18 | // Store represents a distributed key-value store 19 | type Store struct { 20 | mu sync.RWMutex 21 | raft *raft.Node 22 | store map[string]interface{} 23 | } 24 | 25 | // NewStore creates a new distributed key-value store 26 | func NewStore(raftNode *raft.Node) *Store { 27 | s := &Store{ 28 | raft: raftNode, 29 | store: make(map[string]interface{}), 30 | } 31 | 32 | // Start applying committed entries 33 | go s.applyCommittedEntries() 34 | 35 | return s 36 | } 37 | 38 | // Get retrieves a value from the store 39 | func (s *Store) Get(key string) (interface{}, error) { 40 | s.mu.RLock() 41 | defer s.mu.RUnlock() 42 | 43 | if value, ok := s.store[key]; ok { 44 | return value, nil 45 | } 46 | return nil, errors.New("key not found") 47 | } 48 | 49 | // Set sets a value in the store 50 | func (s *Store) Set(key string, value interface{}) error { 51 | cmd := Command{ 52 | Op: "SET", 53 | Key: key, 54 | Value: value, 55 | } 56 | 57 | if _, err := json.Marshal(cmd); err != nil { 58 | return err 59 | } 60 | 61 | // Apply the change locally immediately 62 | s.mu.Lock() 63 | s.store[key] = value 64 | s.mu.Unlock() 65 | 66 | // TODO: Submit command to Raft log 67 | // This would be implemented when we add the actual RPC layer 68 | return nil 69 | } 70 | 71 | // Delete removes a value from the store 72 | func (s *Store) Delete(key string) error { 73 | cmd := Command{ 74 | Op: "DELETE", 75 | Key: key, 76 | } 77 | 78 | if _, err := json.Marshal(cmd); err != nil { 79 | return err 80 | } 81 | 82 | // Apply the change locally immediately 83 | s.mu.Lock() 84 | delete(s.store, key) 85 | s.mu.Unlock() 86 | 87 | // TODO: Submit command to Raft log 88 | // This would be implemented when we add the actual RPC layer 89 | return nil 90 | } 91 | 92 | // applyCommittedEntries applies committed entries from the Raft log 93 | func (s *Store) applyCommittedEntries() { 94 | for { 95 | select { 96 | case entry := <-s.raft.GetApplyCh(): 97 | var cmd Command 98 | if err := json.Unmarshal(entry.([]byte), &cmd); err != nil { 99 | continue 100 | } 101 | 102 | s.mu.Lock() 103 | switch cmd.Op { 104 | case "SET": 105 | s.store[cmd.Key] = cmd.Value 106 | case "DELETE": 107 | delete(s.store, cmd.Key) 108 | } 109 | s.mu.Unlock() 110 | } 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /telemetry/go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= 4 | github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= 5 | github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= 6 | github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= 7 | github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= 8 | github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= 9 | github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 10 | github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= 11 | github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 12 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 13 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 14 | github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= 15 | github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 16 | go.opentelemetry.io/otel v1.32.0 h1:WnBN+Xjcteh0zdk01SVqV55d/m62NJLJdIyb4y/WO5U= 17 | go.opentelemetry.io/otel v1.32.0/go.mod h1:00DCVSB0RQcnzlwyTfqtxSm+DRr9hpYrHjNGiBHVQIg= 18 | go.opentelemetry.io/otel/exporters/jaeger v1.17.0 h1:D7UpUy2Xc2wsi1Ras6V40q806WM07rqoCWzXu7Sqy+4= 19 | go.opentelemetry.io/otel/exporters/jaeger v1.17.0/go.mod h1:nPCqOnEH9rNLKqH/+rrUjiMzHJdV1BlpKcTwRTyKkKI= 20 | go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.32.0 h1:cC2yDI3IQd0Udsux7Qmq8ToKAx1XCilTQECZ0KDZyTw= 21 | go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.32.0/go.mod h1:2PD5Ex6z8CFzDbTdOlwyNIUywRr1DN0ospafJM1wJ+s= 22 | go.opentelemetry.io/otel/metric v1.32.0 h1:xV2umtmNcThh2/a/aCP+h64Xx5wsj8qqnkYZktzNa0M= 23 | go.opentelemetry.io/otel/metric v1.32.0/go.mod h1:jH7CIbbK6SH2V2wE16W05BHCtIDzauciCRLoc/SyMv8= 24 | go.opentelemetry.io/otel/sdk v1.32.0 h1:RNxepc9vK59A8XsgZQouW8ue8Gkb4jpWtJm9ge5lEG4= 25 | go.opentelemetry.io/otel/sdk v1.32.0/go.mod h1:LqgegDBjKMmb2GC6/PrTnteJG39I8/vJCAP9LlJXEjU= 26 | go.opentelemetry.io/otel/trace v1.32.0 h1:WIC9mYrXf8TmY/EXuULKc8hR17vE+Hjv2cssQDe03fM= 27 | go.opentelemetry.io/otel/trace v1.32.0/go.mod h1:+i4rkvCraA+tG6AzwloGaCtkx53Fa+L+V8e9a7YvhT8= 28 | golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= 29 | golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 30 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 31 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 32 | -------------------------------------------------------------------------------- /b3TraceId/go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= 4 | github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= 5 | github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= 6 | github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= 7 | github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= 8 | github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= 9 | github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 10 | github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= 11 | github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 12 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 13 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 14 | github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= 15 | github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 16 | go.opentelemetry.io/contrib/propagators/b3 v1.32.0 h1:MazJBz2Zf6HTN/nK/s3Ru1qme+VhWU5hm83QxEP+dvw= 17 | go.opentelemetry.io/contrib/propagators/b3 v1.32.0/go.mod h1:B0s70QHYPrJwPOwD1o3V/R8vETNOG9N3qZf4LDYvA30= 18 | go.opentelemetry.io/otel v1.32.0 h1:WnBN+Xjcteh0zdk01SVqV55d/m62NJLJdIyb4y/WO5U= 19 | go.opentelemetry.io/otel v1.32.0/go.mod h1:00DCVSB0RQcnzlwyTfqtxSm+DRr9hpYrHjNGiBHVQIg= 20 | go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.32.0 h1:cC2yDI3IQd0Udsux7Qmq8ToKAx1XCilTQECZ0KDZyTw= 21 | go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.32.0/go.mod h1:2PD5Ex6z8CFzDbTdOlwyNIUywRr1DN0ospafJM1wJ+s= 22 | go.opentelemetry.io/otel/metric v1.32.0 h1:xV2umtmNcThh2/a/aCP+h64Xx5wsj8qqnkYZktzNa0M= 23 | go.opentelemetry.io/otel/metric v1.32.0/go.mod h1:jH7CIbbK6SH2V2wE16W05BHCtIDzauciCRLoc/SyMv8= 24 | go.opentelemetry.io/otel/sdk v1.32.0 h1:RNxepc9vK59A8XsgZQouW8ue8Gkb4jpWtJm9ge5lEG4= 25 | go.opentelemetry.io/otel/sdk v1.32.0/go.mod h1:LqgegDBjKMmb2GC6/PrTnteJG39I8/vJCAP9LlJXEjU= 26 | go.opentelemetry.io/otel/trace v1.32.0 h1:WIC9mYrXf8TmY/EXuULKc8hR17vE+Hjv2cssQDe03fM= 27 | go.opentelemetry.io/otel/trace v1.32.0/go.mod h1:+i4rkvCraA+tG6AzwloGaCtkx53Fa+L+V8e9a7YvhT8= 28 | golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= 29 | golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 30 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 31 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 32 | -------------------------------------------------------------------------------- /copierConverter/copier.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "github.com/jinzhu/copier" 6 | ) 7 | 8 | type UserDomain struct { 9 | ID string `copier:"Huncoding"` 10 | Name string `copier:"Name"` 11 | Age int8 `copier:"Age"` 12 | LastName string `copier:"LastName"` 13 | Email string `copier:"Email"` 14 | DocumentNumber string `copier:"DocumentNumber"` 15 | Address AddressDomain `copier:"Address"` 16 | } 17 | 18 | type AddressDomain struct { 19 | Street string `copier:"Street"` 20 | Number int `copier:"Number"` 21 | CEP string `copier:"CEP"` 22 | State string `copier:"State"` 23 | City string `copier:"City"` 24 | Complement string `copier:"Complement"` 25 | } 26 | 27 | type UserRequest struct { 28 | ID string `copier:"Huncoding"` 29 | Name string `copier:"Name"` 30 | Age int8 `copier:"Age"` 31 | LastName string `copier:"LastName"` 32 | Email string `copier:"Email"` 33 | DocumentNumber string `copier:"DocumentNumber"` 34 | Address AddressRequest `copier:"Address"` 35 | } 36 | 37 | type AddressRequest struct { 38 | Street string `copier:"Street"` 39 | Number int `copier:"Number"` 40 | CEP string `copier:"CEP"` 41 | State string `copier:"State"` 42 | City string `copier:"City"` 43 | Complement string `copier:"Complement"` 44 | } 45 | 46 | func convertRequestToDomain( 47 | request UserRequest) *UserDomain { 48 | return &UserDomain{ 49 | ID: request.ID, 50 | Name: request.Name, 51 | Age: request.Age, 52 | LastName: request.LastName, 53 | Email: request.Email, 54 | DocumentNumber: request.DocumentNumber, 55 | Address: AddressDomain{ 56 | Street: request.Address.Street, 57 | Number: request.Address.Number, 58 | CEP: request.Address.CEP, 59 | State: request.Address.State, 60 | City: request.Address.City, 61 | Complement: request.Address.Complement, 62 | }, 63 | } 64 | } 65 | 66 | func main() { 67 | userRequest := UserRequest{ 68 | ID: "123", 69 | Name: "HunCoding", 70 | Age: 22, 71 | LastName: "Test", 72 | Email: "test@gmail.com", 73 | DocumentNumber: "12345", 74 | Address: AddressRequest{ 75 | Street: "test rua", 76 | Number: 123, 77 | CEP: "12345", 78 | State: "SP", 79 | City: "SP", 80 | Complement: "Test", 81 | }, 82 | } 83 | 84 | domain := convertRequestToDomain(userRequest) 85 | fmt.Printf("Converted object: %#v \n", domain) 86 | 87 | userDomainCopier := UserDomain{} 88 | err := copier.Copy(&userDomainCopier, &userRequest) 89 | if err != nil { 90 | return 91 | } 92 | fmt.Printf("Converted object with copier: %#v \n", userDomainCopier) 93 | } 94 | -------------------------------------------------------------------------------- /framework-performance-diff/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | "io" 6 | "io/ioutil" 7 | "log" 8 | "net/http" 9 | 10 | "github.com/gin-gonic/gin" 11 | "github.com/go-chi/chi/v5" 12 | "github.com/gofiber/fiber/v2" 13 | "github.com/gorilla/mux" 14 | ) 15 | 16 | type ObjectExample struct { 17 | ID string `json:"id"` 18 | Name string `json:"name"` 19 | Age int `json:"age"` 20 | } 21 | 22 | func main() { 23 | 24 | log.Println("Starting frameworks") 25 | ch := make(chan struct{}) 26 | 27 | go initGinGonic() 28 | go initGoChi() 29 | go initGoFiber() 30 | go initGorillaMux() 31 | 32 | <-ch 33 | } 34 | 35 | func initGinGonic() { 36 | gin.SetMode(gin.ReleaseMode) 37 | router := gin.New() 38 | router.POST("/testGinGonic/:channel", func(c *gin.Context) { 39 | 40 | var objectExample ObjectExample 41 | 42 | if err := c.ShouldBindJSON(&objectExample); err != nil { 43 | c.Status(400) 44 | return 45 | } 46 | 47 | if value, ok := c.Params.Get("channel"); !ok || value != "huncoding" { 48 | c.Status(400) 49 | return 50 | } 51 | 52 | c.JSON(http.StatusOK, objectExample) 53 | return 54 | }) 55 | 56 | router.Run(":8080") 57 | } 58 | 59 | func initGorillaMux() { 60 | router := mux.NewRouter() 61 | router.HandleFunc("/testGorillaMux/{channel}", func(w http.ResponseWriter, r *http.Request) { 62 | var objectExample ObjectExample 63 | 64 | if value, ok := mux.Vars(r)["channel"]; !ok || value != "huncoding" { 65 | w.WriteHeader(http.StatusBadRequest) 66 | return 67 | } 68 | 69 | b, err := io.ReadAll(r.Body) 70 | if err != nil { 71 | w.WriteHeader(http.StatusBadRequest) 72 | return 73 | } 74 | 75 | if err := json.Unmarshal(b, &objectExample); err != nil { 76 | w.WriteHeader(http.StatusBadRequest) 77 | return 78 | } 79 | 80 | w.WriteHeader(http.StatusOK) 81 | jsonValue, err := json.Marshal(objectExample) 82 | w.Write(jsonValue) 83 | return 84 | 85 | }).Methods("POST") 86 | 87 | http.ListenAndServe(":8081", router) 88 | } 89 | 90 | func initGoChi() { 91 | r := chi.NewRouter() 92 | r.Post("/testGoChi/{channel}", func(w http.ResponseWriter, r *http.Request) { 93 | var objectExample ObjectExample 94 | 95 | channel := chi.URLParam(r, "channel") 96 | if channel != "huncoding" { 97 | w.WriteHeader(http.StatusBadRequest) 98 | return 99 | } 100 | 101 | b, err := io.ReadAll(r.Body) 102 | if err != nil { 103 | w.WriteHeader(http.StatusBadRequest) 104 | return 105 | } 106 | 107 | if err := json.Unmarshal(b, &objectExample); err != nil { 108 | w.WriteHeader(http.StatusBadRequest) 109 | return 110 | } 111 | 112 | w.WriteHeader(http.StatusOK) 113 | jsonValue, err := json.Marshal(objectExample) 114 | w.Write(jsonValue) 115 | return 116 | }) 117 | 118 | http.ListenAndServe(":8082", r) 119 | } 120 | 121 | func initGoFiber() { 122 | app := fiber.New() 123 | log.SetOutput(ioutil.Discard) 124 | app.Post("/testGoFiber/:channel", func(c *fiber.Ctx) error { 125 | 126 | var objectExample ObjectExample 127 | 128 | if value := c.Params("channel"); value != "huncoding" { 129 | return c.Status(400).Send(nil) 130 | } 131 | 132 | if err := c.BodyParser(&objectExample); err != nil { 133 | return c.Status(400).Send(nil) 134 | } 135 | 136 | return c.Status(http.StatusOK).JSON(objectExample) 137 | }) 138 | 139 | app.Listen(":8083") 140 | } 141 | -------------------------------------------------------------------------------- /consensus/pkg/api/server.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | import ( 4 | "encoding/json" 5 | "log" 6 | "net/http" 7 | 8 | "consensus/pkg/raft" 9 | "consensus/pkg/store" 10 | ) 11 | 12 | // Server represents the HTTP API server 13 | type Server struct { 14 | store *store.Store 15 | raft *raft.Node 16 | } 17 | 18 | // NewServer creates a new HTTP API server 19 | func NewServer(store *store.Store, raftNode *raft.Node) *Server { 20 | return &Server{ 21 | store: store, 22 | raft: raftNode, 23 | } 24 | } 25 | 26 | // Start starts the HTTP server 27 | func (s *Server) Start(addr string) error { 28 | http.HandleFunc("/get", s.handleGet) 29 | http.HandleFunc("/set", s.handleSet) 30 | http.HandleFunc("/delete", s.handleDelete) 31 | http.HandleFunc("/state", s.handleState) 32 | 33 | log.Printf("Starting HTTP server on %s", addr) 34 | return http.ListenAndServe(addr, nil) 35 | } 36 | 37 | // handleState handles requests to get the node's state 38 | func (s *Server) handleState(w http.ResponseWriter, r *http.Request) { 39 | if r.Method != http.MethodGet { 40 | http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) 41 | return 42 | } 43 | 44 | state, term := s.raft.GetState() 45 | 46 | // Converter o estado para string 47 | var stateStr string 48 | switch state { 49 | case raft.Follower: 50 | stateStr = "Follower" 51 | case raft.Candidate: 52 | stateStr = "Candidate" 53 | case raft.Leader: 54 | stateStr = "Leader" 55 | } 56 | 57 | json.NewEncoder(w).Encode(map[string]interface{}{ 58 | "state": stateStr, 59 | "term": term, 60 | }) 61 | } 62 | 63 | // handleGet handles GET requests 64 | func (s *Server) handleGet(w http.ResponseWriter, r *http.Request) { 65 | if r.Method != http.MethodGet { 66 | http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) 67 | return 68 | } 69 | 70 | key := r.URL.Query().Get("key") 71 | if key == "" { 72 | http.Error(w, "Key is required", http.StatusBadRequest) 73 | return 74 | } 75 | 76 | value, err := s.store.Get(key) 77 | if err != nil { 78 | http.Error(w, err.Error(), http.StatusNotFound) 79 | return 80 | } 81 | 82 | json.NewEncoder(w).Encode(map[string]interface{}{ 83 | "key": key, 84 | "value": value, 85 | }) 86 | } 87 | 88 | // handleSet handles SET requests 89 | func (s *Server) handleSet(w http.ResponseWriter, r *http.Request) { 90 | if r.Method != http.MethodPost { 91 | http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) 92 | return 93 | } 94 | 95 | var req struct { 96 | Key string `json:"key"` 97 | Value interface{} `json:"value"` 98 | } 99 | 100 | if err := json.NewDecoder(r.Body).Decode(&req); err != nil { 101 | http.Error(w, err.Error(), http.StatusBadRequest) 102 | return 103 | } 104 | 105 | if req.Key == "" { 106 | http.Error(w, "Key is required", http.StatusBadRequest) 107 | return 108 | } 109 | 110 | if err := s.store.Set(req.Key, req.Value); err != nil { 111 | http.Error(w, err.Error(), http.StatusInternalServerError) 112 | return 113 | } 114 | 115 | w.WriteHeader(http.StatusOK) 116 | } 117 | 118 | // handleDelete handles DELETE requests 119 | func (s *Server) handleDelete(w http.ResponseWriter, r *http.Request) { 120 | if r.Method != http.MethodDelete { 121 | http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) 122 | return 123 | } 124 | 125 | key := r.URL.Query().Get("key") 126 | if key == "" { 127 | http.Error(w, "Key is required", http.StatusBadRequest) 128 | return 129 | } 130 | 131 | if err := s.store.Delete(key); err != nil { 132 | http.Error(w, err.Error(), http.StatusInternalServerError) 133 | return 134 | } 135 | 136 | w.WriteHeader(http.StatusOK) 137 | } 138 | -------------------------------------------------------------------------------- /framework-performance-diff/bench_framework_web_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "encoding/json" 6 | "fmt" 7 | "net/http" 8 | "testing" 9 | "time" 10 | ) 11 | 12 | func BenchmarkFrameworksWeb(b *testing.B) { 13 | 14 | ginGonic := "http://localhost:8080/testGinGonic" 15 | gorillaMux := "http://localhost:8081/testGorillaMux" 16 | goChi := "http://localhost:8082/testGoChi" 17 | goFiber := "http://localhost:8083/testGoFiber" 18 | 19 | type bench struct { 20 | name string 21 | paramName string 22 | resultExpected int64 23 | endpoint string 24 | body []byte 25 | } 26 | 27 | obj := ObjectExample{ 28 | ID: "test", 29 | Name: "TEST", 30 | Age: 100, 31 | } 32 | bt, _ := json.Marshal(obj) 33 | 34 | var tests []bench = []bench{ 35 | { 36 | name: "tests_with_the_right_value_GINGONIC", 37 | paramName: "huncoding", 38 | resultExpected: 200, 39 | endpoint: ginGonic, 40 | body: bt, 41 | }, 42 | { 43 | name: "tests_with_the_wrong_value_GINGONIC", 44 | paramName: "TEST", 45 | resultExpected: 400, 46 | endpoint: ginGonic, 47 | body: bt, 48 | }, 49 | { 50 | name: "tests_with_the_wrong_body_GINGONIC", 51 | paramName: "huncoding", 52 | resultExpected: 400, 53 | endpoint: ginGonic, 54 | body: nil, 55 | }, 56 | { 57 | name: "tests_with_the_right_value_GORILLAMUX", 58 | paramName: "huncoding", 59 | resultExpected: 200, 60 | endpoint: gorillaMux, 61 | body: bt, 62 | }, 63 | { 64 | name: "tests_with_the_wrong_value_GORILLAMUX", 65 | paramName: "TEST", 66 | resultExpected: 400, 67 | body: bt, 68 | endpoint: gorillaMux, 69 | }, 70 | { 71 | name: "tests_with_the_wrong_body_GORILLAMUX", 72 | paramName: "huncoding", 73 | resultExpected: 400, 74 | endpoint: gorillaMux, 75 | body: nil, 76 | }, 77 | { 78 | name: "tests_with_the_right_value_GOCHI", 79 | paramName: "huncoding", 80 | resultExpected: 200, 81 | endpoint: goChi, 82 | body: bt, 83 | }, 84 | { 85 | name: "tests_with_the_wrong_value_GOCHI", 86 | paramName: "TEST", 87 | resultExpected: 400, 88 | endpoint: goChi, 89 | body: bt, 90 | }, 91 | { 92 | name: "tests_with_the_wrong_body_GOCHI", 93 | paramName: "huncoding", 94 | resultExpected: 400, 95 | endpoint: goChi, 96 | body: nil, 97 | }, 98 | { 99 | name: "tests_with_the_right_value_GOFIBER", 100 | paramName: "huncoding", 101 | resultExpected: 200, 102 | endpoint: goFiber, 103 | body: bt, 104 | }, 105 | { 106 | name: "tests_with_the_wrong_value_GOFIBER", 107 | paramName: "TEST", 108 | resultExpected: 400, 109 | endpoint: goFiber, 110 | body: bt, 111 | }, 112 | { 113 | name: "tests_with_the_wrong_body_GOFIBER", 114 | paramName: "huncoding", 115 | resultExpected: 400, 116 | endpoint: goFiber, 117 | body: nil, 118 | }, 119 | } 120 | 121 | go initGinGonic() 122 | go initGoChi() 123 | go initGoFiber() 124 | go initGorillaMux() 125 | 126 | time.Sleep(2 * time.Millisecond) 127 | 128 | for _, test := range tests { 129 | b.Run(test.name, func(bf *testing.B) { 130 | bf.ReportAllocs() 131 | for i := 0; i < bf.N; i++ { 132 | if result := callEndpoint(test.paramName, test.endpoint, test.body); result != test.resultExpected { 133 | bf.Errorf(` 134 | %s - Result is different than expected. 135 | expected=%d, 136 | got=%d`, 137 | test.name, 138 | test.resultExpected, 139 | result, 140 | ) 141 | return 142 | } 143 | } 144 | }) 145 | } 146 | 147 | } 148 | 149 | func callEndpoint(param string, path string, body []byte) int64 { 150 | res, err := http.Post( 151 | fmt.Sprintf("%s/%s", path, param), 152 | "application/json", 153 | bytes.NewReader(body)) 154 | if err != nil { 155 | panic(err) 156 | } 157 | 158 | return int64(res.StatusCode) 159 | } 160 | -------------------------------------------------------------------------------- /reverseProxyNoCache/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "crypto/sha256" 6 | "fmt" 7 | "io" 8 | "log" 9 | "math/rand" 10 | "net/http" 11 | "net/url" 12 | "sync" 13 | "time" 14 | ) 15 | 16 | type Cache struct { 17 | data map[string][]byte 18 | ttl map[string]time.Time 19 | mu sync.RWMutex 20 | } 21 | 22 | type ReverseProxy struct { 23 | routes map[string][]string 24 | cache Cache 25 | } 26 | 27 | func NewCache() *Cache { 28 | return &Cache{ 29 | data: make(map[string][]byte), 30 | ttl: make(map[string]time.Time), 31 | } 32 | } 33 | 34 | func NewReverseProxy() *ReverseProxy { 35 | return &ReverseProxy{ 36 | routes: map[string][]string{ 37 | "/todos/1": { 38 | "https://jsonplaceholder.typicode.com", 39 | "https://jsonplaceholder.typicode.com", 40 | }, 41 | }, 42 | cache: *NewCache(), 43 | } 44 | } 45 | 46 | func (c *Cache) Get(key string) ([]byte, bool) { 47 | c.mu.RLock() 48 | defer c.mu.RUnlock() 49 | 50 | if expiration, exist := c.ttl[key]; exist && time.Now().Before(expiration) { 51 | return c.data[key], true 52 | } 53 | 54 | return nil, false 55 | } 56 | 57 | func (c *Cache) Set(key string, value []byte, ttl time.Duration) { 58 | c.mu.Lock() 59 | defer c.mu.Unlock() 60 | 61 | c.data[key] = value 62 | c.ttl[key] = time.Now().Add(ttl) 63 | } 64 | 65 | func (c *Cache) CleanUp() { 66 | c.mu.Lock() 67 | defer c.mu.Unlock() 68 | 69 | for key, expiration := range c.ttl { 70 | if time.Now().After(expiration) { 71 | delete(c.data, key) 72 | delete(c.ttl, key) 73 | } 74 | } 75 | } 76 | 77 | func (rp *ReverseProxy) cacheMiddleware(next http.HandlerFunc) http.HandlerFunc { 78 | return func(w http.ResponseWriter, r *http.Request) { 79 | key := fmt.Sprintf("%s-%x", r.URL.Path, sha256.Sum256([]byte(r.URL.RawQuery))) 80 | if cache, ok := rp.cache.Get(key); ok { 81 | w.Write(cache) 82 | fmt.Printf("Cache hit: %s\n", r.URL.Path) 83 | return 84 | } 85 | 86 | recorder := &responseRecorder{ 87 | ResponseWriter: w, 88 | body: bytes.NewBuffer(nil), 89 | } 90 | next(recorder, r) 91 | rp.cache.Set(key, recorder.body.Bytes(), 5) 92 | } 93 | } 94 | 95 | type responseRecorder struct { 96 | http.ResponseWriter 97 | body *bytes.Buffer 98 | } 99 | 100 | func (r *responseRecorder) Write(b []byte) (int, error) { 101 | r.body.Write(b) 102 | return r.ResponseWriter.Write(b) 103 | } 104 | 105 | func (rp *ReverseProxy) selectBackend(route string) (string, bool) { 106 | backends, exists := rp.routes[route] 107 | if !exists || len(backends) == 0 { 108 | return "", false 109 | } 110 | return backends[rand.Intn(len(backends))], true 111 | } 112 | 113 | func transformResponse(body []byte) []byte { 114 | return bytes.ReplaceAll(body, []byte("userId"), []byte("user_id")) 115 | } 116 | 117 | func (rp *ReverseProxy) ServeHTTP(w http.ResponseWriter, r *http.Request) { 118 | backend, ok := rp.selectBackend(r.URL.Path) 119 | if !ok { 120 | http.Error(w, "No backend found", http.StatusBadGateway) 121 | return 122 | } 123 | 124 | targetURL, err := url.Parse(backend) 125 | if err != nil { 126 | http.Error(w, "Invalid backend URL", http.StatusInternalServerError) 127 | return 128 | } 129 | 130 | proxyReq, err := http.NewRequest(r.Method, targetURL.String()+r.URL.Path, r.Body) 131 | if err != nil { 132 | http.Error(w, "Error creating proxy request", http.StatusInternalServerError) 133 | return 134 | } 135 | proxyReq.Header = r.Header 136 | 137 | start := time.Now() 138 | resp, err := http.DefaultClient.Do(proxyReq) 139 | if err != nil { 140 | http.Error(w, "Error forwarding request", http.StatusBadGateway) 141 | log.Printf("Error forwarding to backend: %v", err) 142 | return 143 | } 144 | defer resp.Body.Close() 145 | 146 | body, err := io.ReadAll(resp.Body) 147 | if err != nil { 148 | http.Error(w, "Error reading response body", http.StatusInternalServerError) 149 | return 150 | } 151 | 152 | body = transformResponse(body) 153 | 154 | for k, v := range resp.Header { 155 | w.Header()[k] = v 156 | } 157 | w.WriteHeader(resp.StatusCode) 158 | w.Write(body) 159 | 160 | log.Printf("Request: %s, Backend: %s, Duration: %s", r.URL.Path, backend, time.Since(start)) 161 | } 162 | 163 | func main() { 164 | rand.Seed(time.Now().UnixNano()) 165 | proxy := NewReverseProxy() 166 | 167 | http.HandleFunc("/", proxy.cacheMiddleware(proxy.ServeHTTP)) 168 | 169 | log.Fatal(http.ListenAndServe(":8080", nil)) 170 | } 171 | -------------------------------------------------------------------------------- /error_handling/go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= 4 | github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= 5 | github.com/gin-gonic/gin v1.7.7 h1:3DoBmSbJbZAWqXJC3SLjAPfutPJJRN1U5pALB7EeTTs= 6 | github.com/gin-gonic/gin v1.7.7/go.mod h1:axIBovoeJpVj8S3BwE0uPMTeReE4+AfFtqpqaZ1qq1U= 7 | github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= 8 | github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= 9 | github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= 10 | github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= 11 | github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= 12 | github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE= 13 | github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= 14 | github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I= 15 | github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= 16 | github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 17 | github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns= 18 | github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= 19 | github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= 20 | github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= 21 | github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= 22 | github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= 23 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= 24 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 25 | github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg= 26 | github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= 27 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 28 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 29 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 30 | github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= 31 | github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= 32 | github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= 33 | github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= 34 | github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= 35 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 36 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= 37 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 38 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 39 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 40 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 41 | golang.org/x/sys v0.0.0-20200116001909-b77594299b42 h1:vEOn+mP2zCOVzKckCZy6YsCtDblrpj/w7B9nxGNELpg= 42 | golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 43 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 44 | golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= 45 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 46 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 47 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 48 | gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= 49 | gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 50 | -------------------------------------------------------------------------------- /bancos-de-dados/mongodb/go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= 4 | github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= 5 | github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= 6 | github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= 7 | github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 8 | github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc= 9 | github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= 10 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= 11 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 12 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= 13 | github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= 14 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= 15 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 16 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 17 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 18 | github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 19 | github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= 20 | github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= 21 | github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= 22 | github.com/xdg-go/scram v1.0.2 h1:akYIkZ28e6A96dkWNJQu3nmCzH3YfwMPQExUYDaRv7w= 23 | github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= 24 | github.com/xdg-go/stringprep v1.0.2 h1:6iq84/ryjjeRmMJwxutI51F2GIPlP5BfTvXHeYjyhBc= 25 | github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= 26 | github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM6xpdFEAYOk8iySO56hMFq6uLyA= 27 | github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= 28 | go.mongodb.org/mongo-driver v1.8.4 h1:NruvZPPL0PBcRJKmbswoWSrmHeUvzdxA3GCPfD/NEOA= 29 | go.mongodb.org/mongo-driver v1.8.4/go.mod h1:0sQWfOeY63QTntERDJJ/0SuKK0T1uVSgKCuAROlKEPY= 30 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 31 | golang.org/x/crypto v0.0.0-20201216223049-8b5274cf687f h1:aZp0e2vLN4MToVqnjNEYEtrEA8RH8U8FN1CU7JgqsPU= 32 | golang.org/x/crypto v0.0.0-20201216223049-8b5274cf687f/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= 33 | golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 34 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 35 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 36 | golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY= 37 | golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 38 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 39 | golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 40 | golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= 41 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 42 | golang.org/x/text v0.3.5 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ= 43 | golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 44 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 45 | golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= 46 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 47 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 48 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 49 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 50 | -------------------------------------------------------------------------------- /consensus/pkg/raft/rpc.go: -------------------------------------------------------------------------------- 1 | package raft 2 | 3 | import ( 4 | "log" 5 | "net" 6 | "net/rpc" 7 | ) 8 | 9 | // RPCServer represents the RPC server for a Raft node 10 | type RPCServer struct { 11 | node *Node 12 | } 13 | 14 | // RequestVote handles the RequestVote RPC 15 | func (s *RPCServer) RequestVote(args *RequestVoteArgs, reply *RequestVoteReply) error { 16 | s.node.mu.Lock() 17 | defer s.node.mu.Unlock() 18 | 19 | reply.Term = s.node.currentTerm 20 | reply.VoteGranted = false 21 | 22 | // If the request is from an old term, reject it 23 | if args.Term < s.node.currentTerm { 24 | log.Printf("Node %s rejecting vote request from %s for term %d (current term: %d)", 25 | s.node.config.ID, args.CandidateID, args.Term, s.node.currentTerm) 26 | return nil 27 | } 28 | 29 | // If we discover a higher term, become follower 30 | if args.Term > s.node.currentTerm { 31 | log.Printf("Node %s discovered higher term %d from %s, becoming follower", 32 | s.node.config.ID, args.Term, args.CandidateID) 33 | s.node.becomeFollower(args.Term) 34 | } 35 | 36 | // Check if we can vote for this candidate 37 | if s.node.votedFor == "" || s.node.votedFor == args.CandidateID { 38 | // Check if candidate's log is at least as up-to-date as ours 39 | lastLogIndex := len(s.node.log) - 1 40 | lastLogTerm := s.node.log[lastLogIndex].Term 41 | 42 | if args.LastLogTerm > lastLogTerm || 43 | (args.LastLogTerm == lastLogTerm && args.LastLogIndex >= lastLogIndex) { 44 | s.node.votedFor = args.CandidateID 45 | reply.VoteGranted = true 46 | log.Printf("Node %s granting vote to %s for term %d", 47 | s.node.config.ID, args.CandidateID, args.Term) 48 | } else { 49 | log.Printf("Node %s rejecting vote for %s: log not up-to-date", 50 | s.node.config.ID, args.CandidateID) 51 | } 52 | } else { 53 | log.Printf("Node %s already voted for %s in term %d", 54 | s.node.config.ID, s.node.votedFor, s.node.currentTerm) 55 | } 56 | 57 | return nil 58 | } 59 | 60 | // AppendEntries handles the AppendEntries RPC 61 | func (s *RPCServer) AppendEntries(args *AppendEntriesArgs, reply *AppendEntriesReply) error { 62 | s.node.mu.Lock() 63 | defer s.node.mu.Unlock() 64 | 65 | reply.Term = s.node.currentTerm 66 | reply.Success = false 67 | 68 | // If the request is from an old term, reject it 69 | if args.Term < s.node.currentTerm { 70 | log.Printf("Node %s rejecting append entries from %s for term %d (current term: %d)", 71 | s.node.config.ID, args.LeaderID, args.Term, s.node.currentTerm) 72 | return nil 73 | } 74 | 75 | // If we discover a higher term, become follower 76 | if args.Term > s.node.currentTerm { 77 | log.Printf("Node %s discovered higher term %d from %s, becoming follower", 78 | s.node.config.ID, args.Term, args.LeaderID) 79 | s.node.becomeFollower(args.Term) 80 | } 81 | 82 | // Reset election timer 83 | s.node.votedFor = "" 84 | 85 | // Check if log is consistent 86 | if args.PrevLogIndex >= len(s.node.log) { 87 | log.Printf("Node %s rejecting append entries: prevLogIndex %d >= log length %d", 88 | s.node.config.ID, args.PrevLogIndex, len(s.node.log)) 89 | return nil 90 | } 91 | 92 | if args.PrevLogIndex > 0 && s.node.log[args.PrevLogIndex].Term != args.PrevLogTerm { 93 | log.Printf("Node %s rejecting append entries: term mismatch at index %d", 94 | s.node.config.ID, args.PrevLogIndex) 95 | return nil 96 | } 97 | 98 | // Append new entries 99 | if len(args.Entries) > 0 { 100 | s.node.log = s.node.log[:args.PrevLogIndex+1] 101 | s.node.log = append(s.node.log, args.Entries...) 102 | log.Printf("Node %s appended %d entries from leader %s", 103 | s.node.config.ID, len(args.Entries), args.LeaderID) 104 | } 105 | 106 | // Update commit index 107 | if args.LeaderCommit > s.node.commitIndex { 108 | s.node.commitIndex = min(args.LeaderCommit, len(s.node.log)-1) 109 | log.Printf("Node %s updated commit index to %d", 110 | s.node.config.ID, s.node.commitIndex) 111 | } 112 | 113 | reply.Success = true 114 | return nil 115 | } 116 | 117 | // StartRPCServer starts the RPC server for the node 118 | func (n *Node) StartRPCServer(addr string) error { 119 | server := &RPCServer{node: n} 120 | rpc.Register(server) 121 | 122 | l, err := net.Listen("tcp", addr) 123 | if err != nil { 124 | return err 125 | } 126 | 127 | go func() { 128 | for { 129 | conn, err := l.Accept() 130 | if err != nil { 131 | log.Printf("Error accepting connection: %v", err) 132 | continue 133 | } 134 | go rpc.ServeConn(conn) 135 | } 136 | }() 137 | 138 | return nil 139 | } 140 | 141 | // min returns the minimum of two integers 142 | func min(a, b int) int { 143 | if a < b { 144 | return a 145 | } 146 | return b 147 | } 148 | -------------------------------------------------------------------------------- /minha-primeira-api/gin-gonic/go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 2 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 3 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 4 | github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= 5 | github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= 6 | github.com/gin-gonic/gin v1.7.7 h1:3DoBmSbJbZAWqXJC3SLjAPfutPJJRN1U5pALB7EeTTs= 7 | github.com/gin-gonic/gin v1.7.7/go.mod h1:axIBovoeJpVj8S3BwE0uPMTeReE4+AfFtqpqaZ1qq1U= 8 | github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= 9 | github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= 10 | github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= 11 | github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= 12 | github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= 13 | github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= 14 | github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE= 15 | github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= 16 | github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I= 17 | github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= 18 | github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 19 | github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns= 20 | github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= 21 | github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= 22 | github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= 23 | github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= 24 | github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= 25 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= 26 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 27 | github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg= 28 | github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= 29 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 30 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 31 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 32 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 33 | github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= 34 | github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= 35 | github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 36 | github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= 37 | github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= 38 | github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= 39 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 40 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= 41 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 42 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 43 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 44 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 45 | golang.org/x/sys v0.0.0-20200116001909-b77594299b42 h1:vEOn+mP2zCOVzKckCZy6YsCtDblrpj/w7B9nxGNELpg= 46 | golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 47 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 48 | golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= 49 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 50 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= 51 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 52 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 53 | gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= 54 | gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 55 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= 56 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 57 | -------------------------------------------------------------------------------- /bad-things/go.sum: -------------------------------------------------------------------------------- 1 | github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= 2 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 4 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 5 | github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= 6 | github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= 7 | github.com/gin-gonic/gin v1.8.1 h1:4+fr/el88TOO3ewCmQr8cx/CtZ/umlIRIs5M4NTNjf8= 8 | github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk= 9 | github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= 10 | github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= 11 | github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU= 12 | github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= 13 | github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho= 14 | github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA= 15 | github.com/go-playground/validator/v10 v10.10.0 h1:I7mrTYv78z8k8VXa/qJlOlEXn/nBh+BF8dHX5nt/dr0= 16 | github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos= 17 | github.com/goccy/go-json v0.9.7 h1:IcB+Aqpx/iMHu5Yooh7jEzJk1JZ7Pjtmys2ukPr7EeM= 18 | github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= 19 | github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= 20 | github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= 21 | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 22 | github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 23 | github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= 24 | github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= 25 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= 26 | github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= 27 | github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= 28 | github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= 29 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 30 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= 31 | github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= 32 | github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= 33 | github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= 34 | github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= 35 | github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= 36 | github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= 37 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= 38 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 39 | github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= 40 | github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= 41 | github.com/pelletier/go-toml/v2 v2.0.1 h1:8e3L2cCQzLFi2CR4g7vGFuFxX7Jl1kKX8gW+iV0GUKU= 42 | github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo= 43 | github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= 44 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 45 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 46 | github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= 47 | github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= 48 | github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= 49 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 50 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 51 | github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 52 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 53 | github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= 54 | github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 55 | github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M= 56 | github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= 57 | github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= 58 | golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 h1:/UOmuWzQfxxo9UtlXMwuQU8CMgg1eZXqTRwkSQJWKOI= 59 | golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= 60 | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 h1:qWPm9rbaAMKs8Bq/9LRpbMqxWRVUAQwMI9fVrssnTfw= 61 | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= 62 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 63 | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 64 | golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 65 | golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069 h1:siQdpVirKtzPhKl3lZWozZraCFObP8S1v6PRp0bLrtU= 66 | golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 67 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 68 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 69 | golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= 70 | golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 71 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 72 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= 73 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 74 | google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= 75 | google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= 76 | google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= 77 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 78 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 79 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= 80 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= 81 | gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= 82 | gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= 83 | gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= 84 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 85 | gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= 86 | gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 87 | -------------------------------------------------------------------------------- /live-reload/go.sum: -------------------------------------------------------------------------------- 1 | github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= 2 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 4 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 5 | github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= 6 | github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= 7 | github.com/gin-gonic/gin v1.8.2 h1:UzKToD9/PoFj/V4rvlKqTRKnQYyz8Sc1MJlv4JHPtvY= 8 | github.com/gin-gonic/gin v1.8.2/go.mod h1:qw5AYuDrzRTnhvusDsrov+fDIxp9Dleuu12h8nfB398= 9 | github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= 10 | github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= 11 | github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU= 12 | github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= 13 | github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho= 14 | github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA= 15 | github.com/go-playground/validator/v10 v10.11.1 h1:prmOlTVv+YjZjmRmNSF3VmspqJIxJWXmqUsHwfTRRkQ= 16 | github.com/go-playground/validator/v10 v10.11.1/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU= 17 | github.com/goccy/go-json v0.9.11 h1:/pAaQDLHEoCq/5FFmSKBswWmK6H0e8g4159Kc/X/nqk= 18 | github.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= 19 | github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= 20 | github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= 21 | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 22 | github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 23 | github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= 24 | github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= 25 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= 26 | github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= 27 | github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= 28 | github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= 29 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 30 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= 31 | github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= 32 | github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= 33 | github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= 34 | github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= 35 | github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= 36 | github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= 37 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= 38 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 39 | github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= 40 | github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= 41 | github.com/pelletier/go-toml/v2 v2.0.6 h1:nrzqCb7j9cDFj2coyLNLaZuJTLjWjlaz6nvTvIwycIU= 42 | github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek= 43 | github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= 44 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 45 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 46 | github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= 47 | github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= 48 | github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= 49 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 50 | github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= 51 | github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= 52 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 53 | github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 54 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 55 | github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 56 | github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= 57 | github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= 58 | github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= 59 | github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M= 60 | github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= 61 | github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= 62 | golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 h1:0es+/5331RGQPcXlMfP+WrnIIS6dNnNRe0WB02W0F4M= 63 | golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= 64 | golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= 65 | golang.org/x/net v0.4.0 h1:Q5QPcMlvfxFTAPV0+07Xz/MpK9NTXu2VDUuy0FeMfaU= 66 | golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= 67 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 68 | golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 69 | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 70 | golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 71 | golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 72 | golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18= 73 | golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 74 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 75 | golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 76 | golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= 77 | golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM= 78 | golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= 79 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 80 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= 81 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 82 | google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= 83 | google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= 84 | google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= 85 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 86 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 87 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= 88 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= 89 | gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= 90 | gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= 91 | gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= 92 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 93 | gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 94 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 95 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 96 | -------------------------------------------------------------------------------- /minha-primeira-api/validando-dados/go.sum: -------------------------------------------------------------------------------- 1 | github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= 2 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 4 | github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= 5 | github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= 6 | github.com/gin-gonic/gin v1.7.7 h1:3DoBmSbJbZAWqXJC3SLjAPfutPJJRN1U5pALB7EeTTs= 7 | github.com/gin-gonic/gin v1.7.7/go.mod h1:axIBovoeJpVj8S3BwE0uPMTeReE4+AfFtqpqaZ1qq1U= 8 | github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= 9 | github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= 10 | github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU= 11 | github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= 12 | github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= 13 | github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho= 14 | github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA= 15 | github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= 16 | github.com/go-playground/validator/v10 v10.10.0 h1:I7mrTYv78z8k8VXa/qJlOlEXn/nBh+BF8dHX5nt/dr0= 17 | github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos= 18 | github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= 19 | github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= 20 | github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= 21 | github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= 22 | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 23 | github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 24 | github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= 25 | github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= 26 | github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= 27 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= 28 | github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= 29 | github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= 30 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 31 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= 32 | github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= 33 | github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= 34 | github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= 35 | github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= 36 | github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= 37 | github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= 38 | github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= 39 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 40 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= 41 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 42 | github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= 43 | github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= 44 | github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= 45 | github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= 46 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 47 | github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= 48 | github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= 49 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 50 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 51 | github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= 52 | github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 53 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 54 | github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= 55 | github.com/ugorji/go v1.2.6 h1:tGiWC9HENWE2tqYycIqFTNorMmFRVhNwCpDOpWqnk8E= 56 | github.com/ugorji/go v1.2.6/go.mod h1:anCg0y61KIhDlPZmnH+so+RQbysYVyDko0IMgJv0Nn0= 57 | github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= 58 | github.com/ugorji/go/codec v1.2.6 h1:7kbGefxLoDBuYXOms4yD7223OpNMMPNPZxXk5TvFcyQ= 59 | github.com/ugorji/go/codec v1.2.6/go.mod h1:V6TCNZ4PHqoHGFZuSG1W8nrCzzdgA2DozYxWFFpvxTw= 60 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 61 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 62 | golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= 63 | golang.org/x/crypto v0.0.0-20220214200702-86341886e292 h1:f+lwQ+GtmgoY+A2YaQxlSOnDjXcQ7ZRLWOHbC6HtRqE= 64 | golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= 65 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 66 | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= 67 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 68 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 69 | golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 70 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 71 | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 72 | golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 73 | golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 74 | golang.org/x/sys v0.0.0-20220224120231-95c6836cb0e7 h1:BXxu8t6QN0G1uff4bzZzSkpsax8+ALqTGUtz08QrV00= 75 | golang.org/x/sys v0.0.0-20220224120231-95c6836cb0e7/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 76 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 77 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 78 | golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= 79 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 80 | golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 81 | golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= 82 | golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= 83 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 84 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 85 | google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= 86 | google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= 87 | google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= 88 | google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= 89 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 90 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 91 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= 92 | gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= 93 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 94 | gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 95 | gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= 96 | gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= 97 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 98 | gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 99 | -------------------------------------------------------------------------------- /test-containers/go.sum: -------------------------------------------------------------------------------- 1 | github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= 2 | github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= 3 | github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= 4 | github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= 5 | github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw= 6 | github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= 7 | github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= 8 | github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= 9 | github.com/containerd/continuity v0.4.2 h1:v3y/4Yz5jwnvqPKJJ+7Wf93fyWoCB3F5EclWG023MDM= 10 | github.com/containerd/continuity v0.4.2/go.mod h1:F6PTNCKepoxEaXLQp3wDAjygEnImnZ/7o4JzpodfroQ= 11 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 12 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 13 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 14 | github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= 15 | github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= 16 | github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= 17 | github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= 18 | github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= 19 | github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= 20 | github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= 21 | github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 22 | github.com/gotestyourself/gotestyourself v2.2.0+incompatible h1:AQwinXlbQR2HvPjQZOmDhRqsv5mZf+Jb1RnSLxcqZcI= 23 | github.com/gotestyourself/gotestyourself v2.2.0+incompatible/go.mod h1:zZKM6oeNM8k+FRljX1mnzVYeS8wiGgQyvST1/GafPbY= 24 | github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc= 25 | github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= 26 | github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= 27 | github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= 28 | github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe h1:iruDEfMl2E6fbMZ9s0scYfZQ84/6SPL6zC8ACM2oIL0= 29 | github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= 30 | github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= 31 | github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= 32 | github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM= 33 | github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= 34 | github.com/opencontainers/runc v1.1.9 h1:XR0VIHTGce5eWPkaPesqTBrhW2yAcaraWfsEalNwQLM= 35 | github.com/opencontainers/runc v1.1.9/go.mod h1:CbUumNnWCuTGFukNXahoo/RFBZvDAgRh/smNYNOhA50= 36 | github.com/ory/dockertest v3.3.5+incompatible h1:iLLK6SQwIhcbrG783Dghaaa3WPzGc+4Emza6EbVUUGA= 37 | github.com/ory/dockertest v3.3.5+incompatible/go.mod h1:1vX4m9wsvi00u5bseYwXaSnhNrne+V0E6LAcBILJdPs= 38 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= 39 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 40 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 41 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 42 | github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= 43 | github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= 44 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 45 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 46 | github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= 47 | github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= 48 | github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= 49 | github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= 50 | github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY= 51 | github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4= 52 | github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8= 53 | github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM= 54 | github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM6xpdFEAYOk8iySO56hMFq6uLyA= 55 | github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= 56 | github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= 57 | go.mongodb.org/mongo-driver v1.12.1 h1:nLkghSU8fQNaK7oUmDhQFsnrtcoNy7Z6LVFKsEecqgE= 58 | go.mongodb.org/mongo-driver v1.12.1/go.mod h1:/rGBTebI3XYboVmgz+Wv3Bcbl3aD0QF9zl6kDDw18rQ= 59 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 60 | golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= 61 | golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d h1:sK3txAijHtOK88l68nt020reeT1ZdKLIYetKl95FzVY= 62 | golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= 63 | golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= 64 | golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= 65 | golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= 66 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 67 | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= 68 | golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= 69 | golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= 70 | golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= 71 | golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= 72 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 73 | golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 74 | golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= 75 | golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 76 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 77 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 78 | golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 79 | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 80 | golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 81 | golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 82 | golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 83 | golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 84 | golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= 85 | golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 86 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 87 | golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= 88 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 89 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 90 | golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 91 | golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= 92 | golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= 93 | golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= 94 | golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= 95 | golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= 96 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 97 | golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 98 | golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= 99 | golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= 100 | golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= 101 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 102 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= 103 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 104 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 105 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 106 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 107 | gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= 108 | gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= 109 | -------------------------------------------------------------------------------- /consensus/pkg/raft/node.go: -------------------------------------------------------------------------------- 1 | package raft 2 | 3 | import ( 4 | "log" 5 | "math/rand" 6 | "net/rpc" 7 | "sync" 8 | "time" 9 | ) 10 | 11 | type Node struct { 12 | mu sync.Mutex 13 | 14 | config *Config 15 | 16 | // Persistent state 17 | currentTerm int 18 | votedFor string 19 | log []LogEntry 20 | 21 | // Volatile state 22 | state NodeState 23 | commitIndex int 24 | lastApplied int 25 | 26 | // Leader state 27 | nextIndex map[string]int 28 | matchIndex map[string]int 29 | 30 | // Channels 31 | applyCh chan interface{} 32 | stopCh chan struct{} 33 | } 34 | 35 | // NewNode creates a new Raft node 36 | func NewNode(config *Config) *Node { 37 | if config == nil { 38 | config = DefaultConfig() 39 | } 40 | 41 | node := &Node{ 42 | config: config, 43 | state: Follower, 44 | nextIndex: make(map[string]int), 45 | matchIndex: make(map[string]int), 46 | applyCh: make(chan interface{}, 100), 47 | stopCh: make(chan struct{}), 48 | } 49 | 50 | // Initialize log with a dummy entry at index 0 51 | node.log = append(node.log, LogEntry{Term: 0}) 52 | 53 | return node 54 | } 55 | 56 | // Start begins the Raft node's main loop 57 | func (n *Node) Start() { 58 | go n.runElectionTimer() 59 | } 60 | 61 | // Stop stops the Raft node 62 | func (n *Node) Stop() { 63 | close(n.stopCh) 64 | } 65 | 66 | // runElectionTimer runs the election timer 67 | func (n *Node) runElectionTimer() { 68 | for { 69 | timeout := n.config.ElectionTimeout + time.Duration(rand.Int63n(int64(n.config.ElectionTimeout))) 70 | log.Printf("Node %s waiting for %v before next election check", n.config.ID, timeout) 71 | 72 | select { 73 | case <-time.After(timeout): 74 | log.Printf("Node %s about to acquire lock in runElectionTimer", n.config.ID) 75 | n.mu.Lock() 76 | log.Printf("Node %s acquired lock in runElectionTimer", n.config.ID) 77 | if n.state != Leader { 78 | log.Printf("Node %s election timeout, current state: %v", n.config.ID, n.state) 79 | go n.startElection() 80 | } 81 | log.Printf("Node %s about to release lock in runElectionTimer", n.config.ID) 82 | n.mu.Unlock() 83 | log.Printf("Node %s released lock in runElectionTimer", n.config.ID) 84 | case <-n.stopCh: 85 | return 86 | } 87 | } 88 | } 89 | 90 | // startElection starts a new election 91 | func (n *Node) startElection() { 92 | log.Printf("Node %s ENTERED startElection", n.config.ID) 93 | 94 | n.mu.Lock() 95 | log.Printf("Node %s acquired lock in startElection", n.config.ID) 96 | 97 | if n.state == Leader { 98 | log.Printf("Node %s is already leader, skipping election", n.config.ID) 99 | n.mu.Unlock() 100 | log.Printf("Node %s EXITING startElection", n.config.ID) 101 | return 102 | } 103 | 104 | log.Printf("Node %s about to set state to Candidate", n.config.ID) 105 | n.state = Candidate 106 | log.Printf("Node %s set state to Candidate", n.config.ID) 107 | 108 | n.currentTerm++ 109 | log.Printf("Node %s incremented currentTerm to %d", n.config.ID, n.currentTerm) 110 | 111 | n.votedFor = n.config.ID 112 | log.Printf("Node %s set votedFor to %s", n.config.ID, n.votedFor) 113 | 114 | currentTerm := n.currentTerm 115 | log.Printf("Node %s set currentTerm local var", n.config.ID) 116 | 117 | if len(n.log) == 0 { 118 | log.Printf("Node %s WARNING: log is empty!", n.config.ID) 119 | } 120 | 121 | log.Printf("Node %s about to unlock mutex", n.config.ID) 122 | n.mu.Unlock() 123 | log.Printf("Node %s unlocked mutex", n.config.ID) 124 | 125 | log.Printf("Node %s starting election for term %d", n.config.ID, currentTerm) 126 | 127 | // Request votes from all peers 128 | votes := 1 // Vote for self 129 | votesCh := make(chan bool, len(n.config.Peers)) 130 | responses := 0 131 | responsesCh := make(chan struct{}, len(n.config.Peers)) 132 | 133 | // Send vote requests to all peers 134 | for _, peer := range n.config.Peers { 135 | log.Printf("Node %s sending RequestVote to %s", n.config.ID, peer) 136 | go func(peer string) { 137 | args := &RequestVoteArgs{ 138 | Term: currentTerm, 139 | CandidateID: n.config.ID, 140 | LastLogIndex: len(n.log) - 1, 141 | LastLogTerm: n.log[len(n.log)-1].Term, 142 | } 143 | reply := &RequestVoteReply{} 144 | 145 | if err := n.sendRequestVote(peer, args, reply); err == nil { 146 | n.mu.Lock() 147 | defer n.mu.Unlock() 148 | 149 | // Check if we're still a candidate for the same term 150 | if n.state != Candidate || n.currentTerm != currentTerm { 151 | return 152 | } 153 | 154 | responses++ 155 | responsesCh <- struct{}{} 156 | 157 | if reply.VoteGranted { 158 | log.Printf("Node %s received vote from %s for term %d", n.config.ID, peer, currentTerm) 159 | votesCh <- true 160 | } else if reply.Term > currentTerm { 161 | log.Printf("Node %s discovered higher term %d from %s, becoming follower", n.config.ID, reply.Term, peer) 162 | n.becomeFollower(reply.Term) 163 | } else { 164 | log.Printf("Node %s did not receive vote from %s for term %d", n.config.ID, peer, currentTerm) 165 | } 166 | } else { 167 | log.Printf("Node %s failed to get vote from %s: %v", n.config.ID, peer, err) 168 | responses++ 169 | responsesCh <- struct{}{} 170 | } 171 | }(peer) 172 | } 173 | 174 | // Wait for votes or timeout 175 | timeout := time.After(n.config.ElectionTimeout) 176 | for { 177 | select { 178 | case <-votesCh: 179 | votes++ 180 | log.Printf("Node %s now has %d votes for term %d", n.config.ID, votes, currentTerm) 181 | if votes > (len(n.config.Peers)+1)/2 { 182 | log.Printf("Node %s received majority of votes (%d) for term %d", n.config.ID, votes, currentTerm) 183 | n.mu.Lock() 184 | if n.state == Candidate && n.currentTerm == currentTerm { 185 | n.becomeLeader() 186 | } 187 | n.mu.Unlock() 188 | log.Printf("Node %s EXITING startElection (became leader)", n.config.ID) 189 | return 190 | } 191 | case <-responsesCh: 192 | if responses == len(n.config.Peers) { 193 | log.Printf("Node %s received all responses but only has %d votes for term %d", 194 | n.config.ID, votes, currentTerm) 195 | log.Printf("Node %s EXITING startElection (all responses)", n.config.ID) 196 | return 197 | } 198 | case <-timeout: 199 | log.Printf("Node %s election timeout for term %d (received %d/%d responses)", 200 | n.config.ID, currentTerm, responses, len(n.config.Peers)) 201 | log.Printf("Node %s EXITING startElection (timeout)", n.config.ID) 202 | return 203 | } 204 | } 205 | } 206 | 207 | // becomeLeader transitions the node to leader state 208 | func (n *Node) becomeLeader() { 209 | if n.state == Leader { 210 | log.Printf("Node %s is already leader for term %d", n.config.ID, n.currentTerm) 211 | return 212 | } 213 | 214 | n.state = Leader 215 | log.Printf("Node %s became leader for term %d", n.config.ID, n.currentTerm) 216 | 217 | // Initialize leader state 218 | for _, peer := range n.config.Peers { 219 | n.nextIndex[peer] = len(n.log) 220 | n.matchIndex[peer] = 0 221 | } 222 | 223 | // Start sending heartbeats immediately 224 | go n.sendHeartbeats() 225 | } 226 | 227 | // becomeFollower transitions the node to follower state 228 | func (n *Node) becomeFollower(term int) { 229 | if n.state == Follower && n.currentTerm == term { 230 | return 231 | } 232 | 233 | n.state = Follower 234 | n.currentTerm = term 235 | n.votedFor = "" 236 | log.Printf("Node %s became follower for term %d", n.config.ID, n.currentTerm) 237 | } 238 | 239 | // sendHeartbeats sends heartbeats to all peers 240 | func (n *Node) sendHeartbeats() { 241 | for { 242 | n.mu.Lock() 243 | if n.state != Leader { 244 | n.mu.Unlock() 245 | return 246 | } 247 | currentTerm := n.currentTerm 248 | n.mu.Unlock() 249 | 250 | // Send heartbeats to all peers 251 | for _, peer := range n.config.Peers { 252 | go func(peer string) { 253 | n.mu.Lock() 254 | args := &AppendEntriesArgs{ 255 | Term: currentTerm, 256 | LeaderID: n.config.ID, 257 | PrevLogIndex: n.nextIndex[peer] - 1, 258 | PrevLogTerm: n.log[n.nextIndex[peer]-1].Term, 259 | Entries: n.log[n.nextIndex[peer]:], 260 | LeaderCommit: n.commitIndex, 261 | } 262 | n.mu.Unlock() 263 | 264 | reply := &AppendEntriesReply{} 265 | if err := n.sendAppendEntries(peer, args, reply); err == nil { 266 | n.mu.Lock() 267 | defer n.mu.Unlock() 268 | 269 | if n.state != Leader || n.currentTerm != currentTerm { 270 | return 271 | } 272 | 273 | if reply.Success { 274 | n.matchIndex[peer] = args.PrevLogIndex + len(args.Entries) 275 | n.nextIndex[peer] = n.matchIndex[peer] + 1 276 | n.updateCommitIndex() 277 | } else if reply.Term > currentTerm { 278 | log.Printf("Node %s discovered higher term %d from %s, becoming follower", n.config.ID, reply.Term, peer) 279 | n.becomeFollower(reply.Term) 280 | } else { 281 | n.nextIndex[peer] = max(1, n.nextIndex[peer]-1) 282 | } 283 | } 284 | }(peer) 285 | } 286 | 287 | time.Sleep(n.config.HeartbeatInterval) 288 | } 289 | } 290 | 291 | // updateCommitIndex updates the commit index 292 | func (n *Node) updateCommitIndex() { 293 | for i := n.commitIndex + 1; i < len(n.log); i++ { 294 | if n.log[i].Term == n.currentTerm { 295 | count := 1 296 | for _, peer := range n.config.Peers { 297 | if n.matchIndex[peer] >= i { 298 | count++ 299 | } 300 | } 301 | if count > len(n.config.Peers)/2 { 302 | n.commitIndex = i 303 | } 304 | } 305 | } 306 | } 307 | 308 | // max returns the maximum of two integers 309 | func max(a, b int) int { 310 | if a > b { 311 | return a 312 | } 313 | return b 314 | } 315 | 316 | // sendRequestVote sends a RequestVote RPC to a peer 317 | func (n *Node) sendRequestVote(peer string, args *RequestVoteArgs, reply *RequestVoteReply) error { 318 | client, err := rpc.Dial("tcp", peer) 319 | if err != nil { 320 | return err 321 | } 322 | defer client.Close() 323 | 324 | return client.Call("RPCServer.RequestVote", args, reply) 325 | } 326 | 327 | // sendAppendEntries sends an AppendEntries RPC to a peer 328 | func (n *Node) sendAppendEntries(peer string, args *AppendEntriesArgs, reply *AppendEntriesReply) error { 329 | client, err := rpc.Dial("tcp", peer) 330 | if err != nil { 331 | return err 332 | } 333 | defer client.Close() 334 | 335 | return client.Call("RPCServer.AppendEntries", args, reply) 336 | } 337 | 338 | // GetApplyCh returns the channel for applying committed entries 339 | func (n *Node) GetApplyCh() <-chan interface{} { 340 | return n.applyCh 341 | } 342 | 343 | // GetState returns the current state and term of the node 344 | func (n *Node) GetState() (NodeState, int) { 345 | n.mu.Lock() 346 | defer n.mu.Unlock() 347 | return n.state, n.currentTerm 348 | } 349 | -------------------------------------------------------------------------------- /framework-performance-diff/go.sum: -------------------------------------------------------------------------------- 1 | github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY= 2 | github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= 3 | github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= 4 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 5 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 6 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 7 | github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= 8 | github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= 9 | github.com/gin-gonic/gin v1.8.1 h1:4+fr/el88TOO3ewCmQr8cx/CtZ/umlIRIs5M4NTNjf8= 10 | github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk= 11 | github.com/go-chi/chi/v5 v5.0.7 h1:rDTPXLDHGATaeHvVlLcR4Qe0zftYethFucbjVQ1PxU8= 12 | github.com/go-chi/chi/v5 v5.0.7/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= 13 | github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= 14 | github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= 15 | github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU= 16 | github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= 17 | github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho= 18 | github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA= 19 | github.com/go-playground/validator/v10 v10.10.0 h1:I7mrTYv78z8k8VXa/qJlOlEXn/nBh+BF8dHX5nt/dr0= 20 | github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos= 21 | github.com/goccy/go-json v0.9.7 h1:IcB+Aqpx/iMHu5Yooh7jEzJk1JZ7Pjtmys2ukPr7EeM= 22 | github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= 23 | github.com/gofiber/fiber/v2 v2.39.0 h1:uhWpYQ6EHN8J7FOPYbI2hrdBD/KNZBC5CjbuOd4QUt4= 24 | github.com/gofiber/fiber/v2 v2.39.0/go.mod h1:Cmuu+elPYGqlvQvdKyjtYsjGMi69PDp8a1AY2I5B2gM= 25 | github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= 26 | github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= 27 | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 28 | github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 29 | github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= 30 | github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= 31 | github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= 32 | github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= 33 | github.com/klauspost/compress v1.15.0 h1:xqfchp4whNFxn5A4XFyyYtitiWI8Hy5EW59jEwcyL6U= 34 | github.com/klauspost/compress v1.15.0/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= 35 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= 36 | github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= 37 | github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= 38 | github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= 39 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 40 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= 41 | github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= 42 | github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= 43 | github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= 44 | github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= 45 | github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= 46 | github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= 47 | github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= 48 | github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= 49 | github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= 50 | github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= 51 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= 52 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 53 | github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= 54 | github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= 55 | github.com/pelletier/go-toml/v2 v2.0.1 h1:8e3L2cCQzLFi2CR4g7vGFuFxX7Jl1kKX8gW+iV0GUKU= 56 | github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo= 57 | github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= 58 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 59 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 60 | github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= 61 | github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= 62 | github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= 63 | github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= 64 | github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= 65 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 66 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 67 | github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 68 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 69 | github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= 70 | github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 71 | github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M= 72 | github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= 73 | github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= 74 | github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= 75 | github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= 76 | github.com/valyala/fasthttp v1.40.0 h1:CRq/00MfruPGFLTQKY8b+8SfdK60TxNztjRMnH0t1Yc= 77 | github.com/valyala/fasthttp v1.40.0/go.mod h1:t/G+3rLek+CyY9bnIE+YlMRddxVAAGjhxndDB4i4C0I= 78 | github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8= 79 | github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= 80 | golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= 81 | golang.org/x/crypto v0.0.0-20220214200702-86341886e292 h1:f+lwQ+GtmgoY+A2YaQxlSOnDjXcQ7ZRLWOHbC6HtRqE= 82 | golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= 83 | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= 84 | golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= 85 | golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc= 86 | golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= 87 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 88 | golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 89 | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 90 | golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 91 | golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 92 | golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 93 | golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab h1:2QkjZIsXupsJbJIdSjjUOgWK3aEtzyuh2mPt3l/CkeU= 94 | golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 95 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 96 | golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= 97 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 98 | golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 99 | golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= 100 | golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= 101 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 102 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= 103 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 104 | google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= 105 | google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= 106 | google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= 107 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 108 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 109 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= 110 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= 111 | gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= 112 | gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= 113 | gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= 114 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 115 | gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= 116 | gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 117 | --------------------------------------------------------------------------------