Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

modify endpoint.gotemplate to implementing service discovery and load balancing on the client side #356

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 5 additions & 1 deletion cmd/_integration-tests/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ SHA := $(shell git rev-parse --short=10 HEAD)

MAKEFILE_PATH := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
VERSION_DATE := $(shell $(MAKEFILE_PATH)/../../commit_date.sh)
BRANCH := $(shell git branch --show-current)

export PATH := $(CURDIR):$(PATH)

Expand All @@ -21,7 +22,10 @@ all: test
test: clean test-transport test-middlewares test-server

truss:
go install -ldflags '-X "main.version=$(SHA)" -X "main.date=$(VERSION_DATE)"' github.com/metaverse/truss/cmd/truss
go install -ldflags '-X "main.version=$(BRANCH).$(SHA)" -X "main.date=$(VERSION_DATE)"' github.com/metaverse/truss/cmd/truss

mytruss:
go build -o mytruss -ldflags '-X "main.version=$(BRANCH).$(SHA)" -X "main.date=$(VERSION_DATE)"' github.com/metaverse/truss/cmd/truss

test-transport: truss
@which truss
Expand Down
2 changes: 1 addition & 1 deletion gengokit/generator/gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import (
"io/ioutil"
"strings"

log "github.com/sirupsen/logrus"
"github.com/pkg/errors"
log "github.com/sirupsen/logrus"

"github.com/metaverse/truss/gengokit"
"github.com/metaverse/truss/gengokit/handlers"
Expand Down
53 changes: 52 additions & 1 deletion gengokit/generator/gen_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package generator

import (
"bytes"
"compress/gzip"
"encoding/hex"
"fmt"
"go/format"
"io"
"io/ioutil"
Expand Down Expand Up @@ -96,7 +100,6 @@ func TestApplyTemplateFromPath(t *testing.T) {
if err != nil {
t.Fatal(err)
}

_, err = testFormat(string(endCode))
if err != nil {
t.Fatal(err)
Expand Down Expand Up @@ -313,3 +316,51 @@ func testFormat(code string) (string, error) {

return string(formatted), nil
}

func compressFile(filePath string) ([]byte, error) {
data, err := ioutil.ReadFile(filePath)
if err != nil {
return nil, fmt.Errorf("read file: %w", err)
}

var buf bytes.Buffer

gzWriter := gzip.NewWriter(&buf)
_, err = gzWriter.Write(data)
if err != nil {
return nil, fmt.Errorf("compress data: %w", err)
}

err = gzWriter.Close()
if err != nil {
return nil, fmt.Errorf("close gzip writer: %w", err)
}

return buf.Bytes(), nil
}

func Test_gzipTemplateContent(t *testing.T) {
// filePath := "../template/NAME-service/svc/client/grpc/client.gotemplate"
filePath := "../template/NAME-service/svc/endpoints.gotemplate"
// filePath := "../template/NAME-service/svc/server/run.gotemplate"
compressedData, err := compressFile(filePath)
if err != nil {
log.Fatal("Compression error:", err)
}

// 将压缩后的数据转换为16进制表示
hexEncoded := hex.EncodeToString(compressedData)
fmt.Println("Compressed data:", hexEncoded)

hexStr := strings.Builder{}
for index := 0; index < len(hexEncoded); index += 2 {
hexStr.WriteString("\\x")
end := index + 2
if end > len(hexEncoded) {
end = len(hexEncoded)
}
hexStr.WriteString(hexEncoded[index:end])
}
fmt.Println("Compressed data2:", hexStr.String())

}
94 changes: 94 additions & 0 deletions gengokit/generator/transport_grpc.gotemplate
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
// Code generated by truss. DO NOT EDIT.
// Rerunning truss will overwrite this file.
// Version: {{.Version}}
// Version Date: {{.VersionDate}}

package svc

// This file provides server-side bindings for the gRPC transport.
// It utilizes the transport/grpc.Server.

import (
"net/http"
"context"

"google.golang.org/grpc/metadata"

grpctransport "github.com/go-kit/kit/transport/grpc"

// This Service
pb "{{.PBImportPath -}}"
)

// MakeGRPCServer makes a set of endpoints available as a gRPC {{.Service.Name}}Server.
func MakeGRPCServer(endpoints Endpoints, options ...grpctransport.ServerOption) pb.{{.Service.Name}}Server {
serverOptions := []grpctransport.ServerOption{
grpctransport.ServerBefore(metadataToContext),
}
serverOptions = append(serverOptions, options...)
return &grpcServer{
// {{ ToLower .Service.Name }}
{{range $i := .Service.Methods}}
{{ToLower $i.Name}}: grpctransport.NewServer(
endpoints.{{$i.Name}}Endpoint,
DecodeGRPC{{$i.Name}}Request,
EncodeGRPC{{$i.Name}}Response,
serverOptions...,
),
{{- end}}
}
}

// grpcServer implements the {{GoName .Service.Name}}Server interface
type grpcServer struct {
{{range $i := .Service.Methods}}
{{ToLower $i.Name}} grpctransport.Handler
{{- end}}
}

// Methods for grpcServer to implement {{GoName .Service.Name}}Server interface
{{range $i := .Service.Methods}}
func (s *grpcServer) {{GoName $i.Name}}(ctx context.Context, req *pb.{{GoName $i.RequestType.Name}}) (*pb.{{GoName $i.ResponseType.Name}}, error) {
_, rep, err := s.{{ToLower $i.Name}}.ServeGRPC(ctx, req)
if err != nil {
return nil, err
}
return rep.(*pb.{{GoName $i.ResponseType.Name}}), nil
}
{{end}}

// Server Decode
{{range $i := .Service.Methods}}
// DecodeGRPC{{$i.Name}}Request is a transport/grpc.DecodeRequestFunc that converts a
// gRPC {{ToLower $i.Name}} request to a user-domain {{ToLower $i.Name}} request. Primarily useful in a server.
func DecodeGRPC{{$i.Name}}Request(_ context.Context, grpcReq interface{}) (interface{}, error) {
req := grpcReq.(*pb.{{GoName $i.RequestType.Name}})
return req, nil
}
{{end}}

// Server Encode
{{range $i := .Service.Methods}}
// EncodeGRPC{{$i.Name}}Response is a transport/grpc.EncodeResponseFunc that converts a
// user-domain {{ToLower $i.Name}} response to a gRPC {{ToLower $i.Name}} reply. Primarily useful in a server.
func EncodeGRPC{{$i.Name}}Response(_ context.Context, response interface{}) (interface{}, error) {
resp := response.(*pb.{{GoName $i.ResponseType.Name}})
return resp, nil
}
{{end}}

// Helpers

func metadataToContext(ctx context.Context, md metadata.MD) context.Context {
for k, v := range md {
if v != nil {
// The key is added both in metadata format (k) which is all lower
// and the http.CanonicalHeaderKey of the key so that it can be
// accessed in either format
ctx = context.WithValue(ctx, k, v[0])
ctx = context.WithValue(ctx, http.CanonicalHeaderKey(k), v[0])
}
}

return ctx
}
50 changes: 50 additions & 0 deletions gengokit/template/NAME-service/svc/endpoints.gotemplate
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// tdl
// Code generated by truss. DO NOT EDIT.
// Rerunning truss will overwrite this file.
// Version: {{.Version}}
Expand All @@ -17,6 +18,7 @@ import (
"github.com/go-kit/kit/endpoint"

pb "{{.PBImportPath -}}"

)

// Endpoints collects all of the endpoints that compose an add service. It's
Expand Down Expand Up @@ -49,6 +51,21 @@ type Endpoints struct {
}
{{end}}

//wrap Make Endpoints
type EndpointMakerWrap interface {
Wrap(service pb.{{.Service.Name}}Server, endpointMakerName string, endpointMaker func(pb.{{.Service.Name}}Server) endpoint.Endpoint) endpoint.Endpoint
}
func NewEndpointMakerWrap() EndpointMakerWrap {
return &endpointMakerWrap{}
}
type endpointMakerWrap struct {
}

func (wrap *endpointMakerWrap) Wrap(service pb.{{.Service.Name}}Server, endpointMakerName string, endpointMaker func(pb.{{.Service.Name}}Server) endpoint.Endpoint) endpoint.Endpoint {
return endpointMaker(service)
}


// Make Endpoints
{{with $te := .}}
{{range $i := $te.Service.Methods}}
Expand Down Expand Up @@ -124,3 +141,36 @@ func (e *Endpoints) WrapAllLabeledExcept(middleware func(string, endpoint.Endpoi
{{- end}}
}
}



// Reserved configuration,
// In order to generate endpoints,they can be expanded in the future
type NewEndpointsOptions struct {
//wrap Endpoint maker(such as Make**Endpoint style) , To achieve service discovery and load balancing in go-kit client.
//service discovery and load balancing example is in https://github.com/go-kit/examples/blob/master/apigateway/main.go:93
EndpointeMakerWrap EndpointMakerWrap
}

func NewEndpoints(service pb.{{.Service.Name}}Server, opts ...func(*NewEndpointsOptions)) Endpoints {
defaultOpts := NewEndpointsOptions{
EndpointeMakerWrap: NewEndpointMakerWrap(),
}
for _, f := range opts {
f(&defaultOpts)
}

// Endpoint domain.
var (
{{range $i := .Service.Methods -}}
{{ToLower $i.Name}}Endpoint = defaultOpts.EndpointeMakerWrap.Wrap(service, "Make{{$i.Name}}Endpoint" ,Make{{$i.Name}}Endpoint)
{{end}}
)
endpoints := Endpoints{
{{range $i := .Service.Methods -}}
{{$i.Name}}Endpoint: {{ToLower $i.Name}}Endpoint,
{{end}}
}

return endpoints
}
12 changes: 1 addition & 11 deletions gengokit/template/NAME-service/svc/server/run.gotemplate
Original file line number Diff line number Diff line change
Expand Up @@ -52,17 +52,7 @@ func NewEndpoints(service pb.{{.Service.Name}}Server) svc.Endpoints {
service = handlers.WrapService(service)

// Endpoint domain.
var (
{{range $i := .Service.Methods -}}
{{ToLower $i.Name}}Endpoint = svc.Make{{$i.Name}}Endpoint(service)
{{end}}
)

endpoints := svc.Endpoints{
{{range $i := .Service.Methods -}}
{{$i.Name}}Endpoint: {{ToLower $i.Name}}Endpoint,
{{end}}
}
endpoints := svc.NewEndpoints(service)

// Wrap selected Endpoints with middlewares. See handlers/middlewares.go
endpoints = handlers.WrapEndpoints(endpoints)
Expand Down