From 6a2b7f56f09aad274e739f612dd12f1af8468fc4 Mon Sep 17 00:00:00 2001 From: Kenta Iwasaki Date: Thu, 11 Jun 2020 21:48:22 +0900 Subject: [PATCH] service, net, cmd/microservice: add microservice example, simplify microservice init code, move http request structure to cmd/flatend --- README.md | 37 +++++++++++++++++++++ cmd/flatend/main.go | 24 ++++++++++++-- cmd/microservice/main.go | 62 ++++++++++------------------------ config.toml | 4 +++ go.mod | 1 + go.sum | 8 +++++ net.go | 6 ---- service.go | 72 ++++++++++++++++++++++++++++++++++++++++ 8 files changed, 161 insertions(+), 53 deletions(-) create mode 100644 service.go diff --git a/README.md b/README.md index 5fa141a..7dd1dd2 100644 --- a/README.md +++ b/README.md @@ -3,3 +3,40 @@ [![MIT License](https://img.shields.io/apm/l/atomic-design-ui.svg?)](LICENSE) [![go.dev reference](https://img.shields.io/badge/go.dev-reference-007d9c?logo=go&logoColor=white&style=flat-square)](https://pkg.go.dev/github.com/lithdew/flatend) [![Discord Chat](https://img.shields.io/discord/697002823123992617)](https://discord.gg/HZEbkeQ) + +```go +package main + +import ( + "github.com/lithdew/flatend" + "strconv" + "sync/atomic" +) + +func check(err error) { + if err != nil { + panic(err) + } +} + +var counter uint64 = 0 + +func handleAllTodos(_ *flatend.Context) []byte { + return strconv.AppendUint(nil, atomic.AddUint64(&counter, 1), 10) +} + +func handleGetTodos(ctx *flatend.Context) []byte { + return ctx.Body() +} + +func main() { + service := &flatend.Service{ + Addr: "127.0.0.1:9000", + Services: map[string]flatend.Handler{ + "all_todos": handleAllTodos, + "get_todos": handleGetTodos, + }, + } + check(service.Start()) +} +``` \ No newline at end of file diff --git a/cmd/flatend/main.go b/cmd/flatend/main.go index 1edfddc..4ff88e8 100644 --- a/cmd/flatend/main.go +++ b/cmd/flatend/main.go @@ -1,10 +1,10 @@ package main import ( - "encoding/json" "errors" "fmt" "github.com/BurntSushi/toml" + jsoniter "github.com/json-iterator/go" "github.com/julienschmidt/httprouter" "github.com/lithdew/flatend" "github.com/lithdew/kademlia" @@ -18,6 +18,15 @@ import ( "time" ) +var json = jsoniter.ConfigCompatibleWithStandardLibrary + +type Request struct { + Header http.Header `json:"header"` + Query url.Values `json:"query"` + Params map[string]string `json:"params"` + Body []byte `json:"body"` +} + type Config struct { HTTP []ConfigHTTP } @@ -206,7 +215,18 @@ func main() { body = nil } - buf, err := json.Marshal(flatend.Message{Header: r.Header, Body: body}) + req := Request{ + Header: r.Header, + Query: r.URL.Query(), + Body: body, + } + + req.Params = make(map[string]string, len(params)) + for _, param := range params { + req.Params[param.Key] = param.Value + } + + buf, err := json.Marshal(req) if err != nil { return } diff --git a/cmd/microservice/main.go b/cmd/microservice/main.go index 466bf2c..bedca02 100644 --- a/cmd/microservice/main.go +++ b/cmd/microservice/main.go @@ -2,61 +2,33 @@ package main import ( "github.com/lithdew/flatend" - "github.com/lithdew/kademlia" - "log" - "net" - "os" - "os/signal" + "strconv" + "sync/atomic" ) -func main() { - Register("127.0.0.1:9000") -} - func check(err error) { if err != nil { panic(err) } } -func Register(hub string) { - _, priv, err := kademlia.GenerateKeys(nil) - check(err) - - addr := "127.0.0.1:12000" +var counter uint64 = 0 - node, err := flatend.NewNode(priv, addr) - check(err) +func handleAllTodos(_ *flatend.Context) []byte { + return strconv.AppendUint(nil, atomic.AddUint64(&counter, 1), 10) +} - //counter := uint64(0) - // - //node.Handle(func(service string, buf []byte) []byte { - // return strconv.AppendUint(nil, atomic.AddUint64(&counter, 1), 10) - //}) +func handleGetTodos(ctx *flatend.Context) []byte { + return ctx.Body() +} - handleGetTodos := func(ctx *flatend.Context) []byte { - return ctx.Body() +func main() { + service := &flatend.Service{ + Addr: "127.0.0.1:9000", + Services: map[string]flatend.Handler{ + "all_todos": handleAllTodos, + "get_todos": handleGetTodos, + }, } - - node.Register("get_todos", handleGetTodos) - - ln, err := net.Listen("tcp", addr) - check(err) - - go func() { - check(node.Serve(ln)) - }() - - defer func() { - node.Shutdown() - check(ln.Close()) - }() - - check(node.Dial(hub)) - - ch := make(chan os.Signal, 1) - signal.Notify(ch, os.Interrupt) - <-ch - - log.Println("Done.") + check(service.Start()) } diff --git a/config.toml b/config.toml index 78ffb3c..bb5e8e3 100644 --- a/config.toml +++ b/config.toml @@ -15,6 +15,10 @@ body_size = 1048576 [[http.routes]] path = "GET /todos" +service = "all_todos" + +[[http.routes]] +path = "GET /todos/:id" service = "get_todos" [[http.routes]] diff --git a/go.mod b/go.mod index de3b8cf..c904589 100644 --- a/go.mod +++ b/go.mod @@ -8,6 +8,7 @@ require ( github.com/BurntSushi/toml v0.3.1 github.com/davecgh/go-spew v1.1.1 github.com/jpillora/backoff v1.0.0 + github.com/json-iterator/go v1.1.10 github.com/julienschmidt/httprouter v1.3.0 github.com/lithdew/bytesutil v0.0.0-20200409052507-d98389230a59 github.com/lithdew/kademlia v0.0.0-20200607181215-ff07ba2ac940 diff --git a/go.sum b/go.sum index 2db98f6..55f8656 100644 --- a/go.sum +++ b/go.sum @@ -4,8 +4,11 @@ github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= +github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= @@ -25,11 +28,16 @@ github.com/lithdew/reliable v0.0.0-20200506103725-7df64908b057 h1:CBhKVPym/7ZzY7 github.com/lithdew/reliable v0.0.0-20200506103725-7df64908b057/go.mod h1:b9iSDHZ4DaCGpwhQdKsH0u61UancBXJMe0r8SCPKEEA= github.com/lithdew/seq v0.0.0-20200504083424-74d5d8117a05 h1:j1UtG8NYCupA5xUwQ/vrTf/zjuNlZ0D1n7UtM8LhS58= github.com/lithdew/seq v0.0.0-20200504083424-74d5d8117a05/go.mod h1:4vVgbfmYc+ZIh0dy99HRrM6knnAtQXNI8MOx+1pUYso= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/oasislabs/ed25519 v0.0.0-20200302143042-29f6767a7c3e h1:85L+lUTJHx4O7UP9y/65XV8iq7oaA2Uqe5WiUSB8XE4= github.com/oasislabs/ed25519 v0.0.0-20200302143042-29f6767a7c3e/go.mod h1:xIpCyrK2ouGA4QBGbiNbkoONrvJ00u9P3QOkXSOAC0c= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= diff --git a/net.go b/net.go index 468c865..6d7bc08 100644 --- a/net.go +++ b/net.go @@ -9,7 +9,6 @@ import ( "io" "math" "net" - "net/http" "strconv" "sync" "unicode/utf8" @@ -197,11 +196,6 @@ func UnmarshalRequestPacket(buf []byte) (RequestPacket, error) { return pkt, nil } -type Message struct { - Header http.Header `json:"header"` - Body []byte `json:"body"` -} - func Addr(host net.IP, port uint16) string { h := "" if len(host) > 0 { diff --git a/service.go b/service.go new file mode 100644 index 0000000..bfeebdd --- /dev/null +++ b/service.go @@ -0,0 +1,72 @@ +package flatend + +import ( + "errors" + "fmt" + "github.com/lithdew/kademlia" + "net" + "os" + "os/signal" +) + +type Service struct { + Addr string + BindAddr string + + PrivateKey kademlia.PrivateKey + Services map[string]Handler +} + +func (s Service) Start() error { + addr := s.Addr + if addr == "" { + return errors.New("address to flatend hub must be provided") + } + + bindAddr := s.BindAddr + if bindAddr == "" { + bindAddr = ":0" + } + + var err error + + privateKey := s.PrivateKey + if privateKey == kademlia.ZeroPrivateKey { + _, privateKey, err = kademlia.GenerateKeys(nil) + if err != nil { + return fmt.Errorf("failed to generate keys: %w", err) + } + } + + ln, err := net.Listen("tcp", bindAddr) + if err != nil { + return fmt.Errorf("failed to listen on bind addr '%s': %w", bindAddr, err) + } + + node, err := NewNode(privateKey, ln.Addr().String()) + if err != nil { + return err + } + + for service, handler := range s.Services { + node.Register(service, handler) + } + + errCh := make(chan error, 1) + go func() { + errCh <- node.Serve(ln) + }() + + if err := node.Dial(addr); err != nil { + return fmt.Errorf("failed to reach flatend hub: %w", err) + } + + ch := make(chan os.Signal, 1) + signal.Notify(ch, os.Interrupt) + <-ch + + node.Shutdown() + ln.Close() + + return <-errCh +}