lint (#57)
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
This commit was merged in pull request #57.
	This commit is contained in:
		
							
								
								
									
										13
									
								
								.github/stale.sh
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										13
									
								
								.github/stale.sh
									
									
									
									
										vendored
									
									
								
							| @@ -1,13 +0,0 @@ | |||||||
| #!/bin/bash -ex |  | ||||||
|  |  | ||||||
| export PATH=$PATH:$(pwd)/bin |  | ||||||
| export GO111MODULE=on |  | ||||||
| export GOBIN=$(pwd)/bin |  | ||||||
|  |  | ||||||
| #go get github.com/rvflash/goup@v0.4.1 |  | ||||||
|  |  | ||||||
| #goup -v ./... |  | ||||||
| #go get github.com/psampaz/go-mod-outdated@v0.6.0 |  | ||||||
| go list -u -m -mod=mod -json all | go-mod-outdated -update -direct -ci || true |  | ||||||
|  |  | ||||||
| #go list -u -m -json all | go-mod-outdated -update |  | ||||||
							
								
								
									
										3
									
								
								.github/workflows/build.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.github/workflows/build.yml
									
									
									
									
										vendored
									
									
								
							| @@ -34,10 +34,9 @@ jobs: | |||||||
|         uses: actions/checkout@v2 |         uses: actions/checkout@v2 | ||||||
|       - name: lint |       - name: lint | ||||||
|         uses: golangci/golangci-lint-action@v2 |         uses: golangci/golangci-lint-action@v2 | ||||||
|         continue-on-error: true |  | ||||||
|         with: |         with: | ||||||
|           # Required: the version of golangci-lint is required and must be specified without patch version: we always use the latest patch version. |           # Required: the version of golangci-lint is required and must be specified without patch version: we always use the latest patch version. | ||||||
|           version: v1.30 |           version: v1.39 | ||||||
|           # Optional: working directory, useful for monorepos |           # Optional: working directory, useful for monorepos | ||||||
|           # working-directory: somedir |           # working-directory: somedir | ||||||
|           # Optional: golangci-lint command line arguments. |           # Optional: golangci-lint command line arguments. | ||||||
|   | |||||||
							
								
								
									
										3
									
								
								.github/workflows/pr.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.github/workflows/pr.yml
									
									
									
									
										vendored
									
									
								
							| @@ -34,10 +34,9 @@ jobs: | |||||||
|         uses: actions/checkout@v2 |         uses: actions/checkout@v2 | ||||||
|       - name: lint |       - name: lint | ||||||
|         uses: golangci/golangci-lint-action@v2 |         uses: golangci/golangci-lint-action@v2 | ||||||
|         continue-on-error: true |  | ||||||
|         with: |         with: | ||||||
|           # Required: the version of golangci-lint is required and must be specified without patch version: we always use the latest patch version. |           # Required: the version of golangci-lint is required and must be specified without patch version: we always use the latest patch version. | ||||||
|           version: v1.30 |           version: v1.39 | ||||||
|           # Optional: working directory, useful for monorepos |           # Optional: working directory, useful for monorepos | ||||||
|           # working-directory: somedir |           # working-directory: somedir | ||||||
|           # Optional: golangci-lint command line arguments. |           # Optional: golangci-lint command line arguments. | ||||||
|   | |||||||
							
								
								
									
										44
									
								
								.golangci.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								.golangci.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | |||||||
|  | run: | ||||||
|  |   concurrency: 4 | ||||||
|  |   deadline: 5m | ||||||
|  |   issues-exit-code: 1 | ||||||
|  |   tests: true | ||||||
|  |  | ||||||
|  | linters-settings: | ||||||
|  |   govet: | ||||||
|  |     check-shadowing: true | ||||||
|  |     enable: | ||||||
|  |       - fieldalignment | ||||||
|  |  | ||||||
|  | linters: | ||||||
|  |   enable: | ||||||
|  |     - govet | ||||||
|  |     - deadcode | ||||||
|  |     - errcheck | ||||||
|  |     - govet | ||||||
|  |     - ineffassign | ||||||
|  |     - staticcheck | ||||||
|  |     - structcheck | ||||||
|  |     - typecheck | ||||||
|  |     - unused | ||||||
|  |     - varcheck | ||||||
|  |     - bodyclose | ||||||
|  |     - gci | ||||||
|  |     - goconst | ||||||
|  |     - gocritic | ||||||
|  |     - gosimple | ||||||
|  |     - gofmt | ||||||
|  |     - gofumpt | ||||||
|  |     - goimports | ||||||
|  |     - golint | ||||||
|  |     - gosec | ||||||
|  |     - makezero | ||||||
|  |     - misspell | ||||||
|  |     - nakedret | ||||||
|  |     - nestif | ||||||
|  |     - nilerr | ||||||
|  |     - noctx | ||||||
|  |     - prealloc | ||||||
|  |     - unconvert | ||||||
|  |     - unparam | ||||||
|  |   disable-all: false | ||||||
							
								
								
									
										36
									
								
								handler.go
									
									
									
									
									
								
							
							
						
						
									
										36
									
								
								handler.go
									
									
									
									
									
								
							| @@ -9,7 +9,6 @@ import ( | |||||||
| 	"strings" | 	"strings" | ||||||
| 	"sync" | 	"sync" | ||||||
|  |  | ||||||
| 	"github.com/unistack-org/micro/v3/codec" |  | ||||||
| 	"github.com/unistack-org/micro/v3/errors" | 	"github.com/unistack-org/micro/v3/errors" | ||||||
| 	"github.com/unistack-org/micro/v3/logger" | 	"github.com/unistack-org/micro/v3/logger" | ||||||
| 	"github.com/unistack-org/micro/v3/metadata" | 	"github.com/unistack-org/micro/v3/metadata" | ||||||
| @@ -22,7 +21,9 @@ import ( | |||||||
| var ( | var ( | ||||||
| 	DefaultErrorHandler = func(ctx context.Context, s server.Handler, w http.ResponseWriter, r *http.Request, err error, status int) { | 	DefaultErrorHandler = func(ctx context.Context, s server.Handler, w http.ResponseWriter, r *http.Request, err error, status int) { | ||||||
| 		w.WriteHeader(status) | 		w.WriteHeader(status) | ||||||
| 		w.Write([]byte(err.Error())) | 		if _, cerr := w.Write([]byte(err.Error())); cerr != nil { | ||||||
|  | 			logger.DefaultLogger.Errorf(ctx, "write failed: %v", cerr) | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
| 	DefaultContentType = "application/json" | 	DefaultContentType = "application/json" | ||||||
| ) | ) | ||||||
| @@ -44,20 +45,6 @@ type httpHandler struct { | |||||||
| 	sync.RWMutex | 	sync.RWMutex | ||||||
| } | } | ||||||
|  |  | ||||||
| func (h *httpHandler) newCodec(ct string) (codec.Codec, error) { |  | ||||||
| 	h.RLock() |  | ||||||
| 	defer h.RUnlock() |  | ||||||
|  |  | ||||||
| 	if idx := strings.IndexRune(ct, ';'); idx >= 0 { |  | ||||||
| 		ct = ct[:idx] |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if cf, ok := h.sopts.Codecs[ct]; ok { |  | ||||||
| 		return cf, nil |  | ||||||
| 	} |  | ||||||
| 	return nil, codec.ErrUnknownContentType |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (h *httpHandler) Name() string { | func (h *httpHandler) Name() string { | ||||||
| 	return h.name | 	return h.name | ||||||
| } | } | ||||||
| @@ -75,7 +62,6 @@ func (h *httpHandler) Options() server.HandlerOptions { | |||||||
| } | } | ||||||
|  |  | ||||||
| func (h *httpServer) ServeHTTP(w http.ResponseWriter, r *http.Request) { | func (h *httpServer) ServeHTTP(w http.ResponseWriter, r *http.Request) { | ||||||
|  |  | ||||||
| 	for exp, ph := range h.pathHandlers { | 	for exp, ph := range h.pathHandlers { | ||||||
| 		if exp.MatchString(r.URL.String()) { | 		if exp.MatchString(r.URL.String()) { | ||||||
| 			ph(w, r) | 			ph(w, r) | ||||||
| @@ -95,7 +81,7 @@ func (h *httpServer) ServeHTTP(w http.ResponseWriter, r *http.Request) { | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	ctx := metadata.NewContext(r.Context(), nil) | 	ctx := metadata.NewIncomingContext(r.Context(), nil) | ||||||
|  |  | ||||||
| 	defer r.Body.Close() | 	defer r.Body.Close() | ||||||
|  |  | ||||||
| @@ -132,8 +118,8 @@ func (h *httpServer) ServeHTTP(w http.ResponseWriter, r *http.Request) { | |||||||
| 	for _, hpat := range h.handlers { | 	for _, hpat := range h.handlers { | ||||||
| 		handlertmp := hpat.(*httpHandler) | 		handlertmp := hpat.(*httpHandler) | ||||||
| 		for _, hldrtmp := range handlertmp.handlers[r.Method] { | 		for _, hldrtmp := range handlertmp.handlers[r.Method] { | ||||||
| 			mp, err := hldrtmp.pat.Match(components, verb) | 			mp, merr := hldrtmp.pat.Match(components, verb) | ||||||
| 			if err == nil { | 			if merr == nil { | ||||||
| 				match = true | 				match = true | ||||||
| 				for k, v := range mp { | 				for k, v := range mp { | ||||||
| 					matches[k] = v | 					matches[k] = v | ||||||
| @@ -161,9 +147,9 @@ func (h *httpServer) ServeHTTP(w http.ResponseWriter, r *http.Request) { | |||||||
|  |  | ||||||
| 	// get fields from url values | 	// get fields from url values | ||||||
| 	if len(r.URL.RawQuery) > 0 { | 	if len(r.URL.RawQuery) > 0 { | ||||||
| 		umd, err := rflutil.URLMap(r.URL.RawQuery) | 		umd, cerr := rflutil.URLMap(r.URL.RawQuery) | ||||||
| 		if err != nil { | 		if cerr != nil { | ||||||
| 			h.errorHandler(ctx, handler, w, r, err, http.StatusBadRequest) | 			h.errorHandler(ctx, handler, w, r, cerr, http.StatusBadRequest) | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
| 		for k, v := range umd { | 		for k, v := range umd { | ||||||
| @@ -284,5 +270,7 @@ func (h *httpServer) ServeHTTP(w http.ResponseWriter, r *http.Request) { | |||||||
| 		// handler.sopts.Logger.Warn(handler.sopts.Context, "response code not set in handler via SetRspCode(ctx, http.StatusXXX)") | 		// handler.sopts.Logger.Warn(handler.sopts.Context, "response code not set in handler via SetRspCode(ctx, http.StatusXXX)") | ||||||
| 		w.WriteHeader(200) | 		w.WriteHeader(200) | ||||||
| 	} | 	} | ||||||
| 	w.Write(b) | 	if _, cerr := w.Write(b); cerr != nil { | ||||||
|  | 		logger.DefaultLogger.Errorf(ctx, "write failed: %v", cerr) | ||||||
|  | 	} | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										34
									
								
								http.go
									
									
									
									
									
								
							
							
						
						
									
										34
									
								
								http.go
									
									
									
									
									
								
							| @@ -126,19 +126,23 @@ func (h *httpServer) Init(opts ...server.Option) error { | |||||||
|  |  | ||||||
| func (h *httpServer) Handle(handler server.Handler) error { | func (h *httpServer) Handle(handler server.Handler) error { | ||||||
| 	h.Lock() | 	h.Lock() | ||||||
| 	if hdlr, ok := handler.(*httpHandler); ok { | 	defer h.Unlock() | ||||||
|  | 	hdlr, ok := handler.(*httpHandler) | ||||||
|  | 	if !ok { | ||||||
|  | 		h.hd = handler | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	if _, ok := hdlr.hd.(http.Handler); ok { | 	if _, ok := hdlr.hd.(http.Handler); ok { | ||||||
| 		h.hd = handler | 		h.hd = handler | ||||||
| 		} else { | 		return nil | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	if h.handlers == nil { | 	if h.handlers == nil { | ||||||
| 		h.handlers = make(map[string]server.Handler) | 		h.handlers = make(map[string]server.Handler) | ||||||
| 	} | 	} | ||||||
| 	h.handlers[handler.Name()] = handler | 	h.handlers[handler.Name()] = handler | ||||||
| 		} |  | ||||||
| 	} else { |  | ||||||
| 		h.hd = handler |  | ||||||
| 	} |  | ||||||
| 	h.Unlock() |  | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -279,7 +283,7 @@ func (h *httpServer) Register() error { | |||||||
| 	service.Endpoints = eps | 	service.Endpoints = eps | ||||||
|  |  | ||||||
| 	h.Lock() | 	h.Lock() | ||||||
| 	var subscriberList []*httpSubscriber | 	subscriberList := make([]*httpSubscriber, 0, len(h.subscribers)) | ||||||
| 	for e := range h.subscribers { | 	for e := range h.subscribers { | ||||||
| 		// Only advertise non internal subscribers | 		// Only advertise non internal subscribers | ||||||
| 		subscriberList = append(subscriberList, e) | 		subscriberList = append(subscriberList, e) | ||||||
| @@ -430,6 +434,7 @@ func (h *httpServer) Start() error { | |||||||
| 	var handler http.Handler | 	var handler http.Handler | ||||||
| 	var srvFunc func(net.Listener) error | 	var srvFunc func(net.Listener) error | ||||||
|  |  | ||||||
|  | 	// nolint: nestif | ||||||
| 	if h.opts.Context != nil { | 	if h.opts.Context != nil { | ||||||
| 		if hs, ok := h.opts.Context.Value(serverKey{}).(*http.Server); ok && hs != nil { | 		if hs, ok := h.opts.Context.Value(serverKey{}).(*http.Server); ok && hs != nil { | ||||||
| 			if hs.Handler == nil && h.hd != nil { | 			if hs.Handler == nil && h.hd != nil { | ||||||
| @@ -485,9 +490,17 @@ func (h *httpServer) Start() error { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if srvFunc != nil { | 	if srvFunc != nil { | ||||||
| 		go srvFunc(ts) | 		go func() { | ||||||
|  | 			if cerr := srvFunc(ts); cerr != nil { | ||||||
|  | 				h.opts.Logger.Error(h.opts.Context, cerr) | ||||||
|  | 			} | ||||||
|  | 		}() | ||||||
| 	} else { | 	} else { | ||||||
| 		go http.Serve(ts, fn) | 		go func() { | ||||||
|  | 			if cerr := http.Serve(ts, fn); cerr != nil { | ||||||
|  | 				h.opts.Logger.Error(h.opts.Context, cerr) | ||||||
|  | 			} | ||||||
|  | 		}() | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	go func() { | 	go func() { | ||||||
| @@ -511,6 +524,7 @@ func (h *httpServer) Start() error { | |||||||
| 				registered := h.registered | 				registered := h.registered | ||||||
| 				h.RUnlock() | 				h.RUnlock() | ||||||
| 				rerr := config.RegisterCheck(h.opts.Context) | 				rerr := config.RegisterCheck(h.opts.Context) | ||||||
|  | 				// nolint: nestif | ||||||
| 				if rerr != nil && registered { | 				if rerr != nil && registered { | ||||||
| 					if config.Logger.V(logger.ErrorLevel) { | 					if config.Logger.V(logger.ErrorLevel) { | ||||||
| 						config.Logger.Errorf(config.Context, "Server %s-%s register check error: %s, deregister it", config.Name, config.Id, rerr) | 						config.Logger.Errorf(config.Context, "Server %s-%s register check error: %s, deregister it", config.Name, config.Id, rerr) | ||||||
|   | |||||||
							
								
								
									
										24
									
								
								options.go
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								options.go
									
									
									
									
									
								
							| @@ -8,11 +8,6 @@ import ( | |||||||
| 	"github.com/unistack-org/micro/v3/server" | 	"github.com/unistack-org/micro/v3/server" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| type rspCodeKey struct{} |  | ||||||
| type rspCodeVal struct { |  | ||||||
| 	code int |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // SetError pass error to caller | // SetError pass error to caller | ||||||
| func SetError(err interface{}) error { | func SetError(err interface{}) error { | ||||||
| 	return &Error{err: err} | 	return &Error{err: err} | ||||||
| @@ -28,6 +23,13 @@ func (err *Error) Error() string { | |||||||
| 	return fmt.Sprintf("%v", err.err) | 	return fmt.Sprintf("%v", err.err) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | type ( | ||||||
|  | 	rspCodeKey struct{} | ||||||
|  | 	rspCodeVal struct { | ||||||
|  | 		code int | ||||||
|  | 	} | ||||||
|  | ) | ||||||
|  |  | ||||||
| // SetRspCode saves response code in context, must be used by handler to specify http code | // SetRspCode saves response code in context, must be used by handler to specify http code | ||||||
| func SetRspCode(ctx context.Context, code int) { | func SetRspCode(ctx context.Context, code int) { | ||||||
| 	if rsp, ok := ctx.Value(rspCodeKey{}).(*rspCodeVal); ok { | 	if rsp, ok := ctx.Value(rspCodeKey{}).(*rspCodeVal); ok { | ||||||
| @@ -65,10 +67,12 @@ func ErrorHandler(fn func(ctx context.Context, s server.Handler, w http.Response | |||||||
| 	return server.SetOption(errorHandlerKey{}, fn) | 	return server.SetOption(errorHandlerKey{}, fn) | ||||||
| } | } | ||||||
|  |  | ||||||
| type pathHandlerKey struct{} | type ( | ||||||
| type pathHandlerVal struct { | 	pathHandlerKey struct{} | ||||||
|  | 	pathHandlerVal struct { | ||||||
| 		h map[string]http.HandlerFunc | 		h map[string]http.HandlerFunc | ||||||
| 	} | 	} | ||||||
|  | ) | ||||||
|  |  | ||||||
| // PathHandler specifies http handler for path regexp | // PathHandler specifies http handler for path regexp | ||||||
| func PathHandler(path string, h http.HandlerFunc) server.Option { | func PathHandler(path string, h http.HandlerFunc) server.Option { | ||||||
| @@ -85,10 +89,12 @@ func PathHandler(path string, h http.HandlerFunc) server.Option { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| type contentTypeHandlerKey struct{} | type ( | ||||||
| type contentTypeHandlerVal struct { | 	contentTypeHandlerKey struct{} | ||||||
|  | 	contentTypeHandlerVal struct { | ||||||
| 		h map[string]http.HandlerFunc | 		h map[string]http.HandlerFunc | ||||||
| 	} | 	} | ||||||
|  | ) | ||||||
|  |  | ||||||
| // ContentTypeHandler specifies http handler for Content-Type | // ContentTypeHandler specifies http handler for Content-Type | ||||||
| func ContentTypeHandler(ct string, h http.HandlerFunc) server.Option { | func ContentTypeHandler(ct string, h http.HandlerFunc) server.Option { | ||||||
|   | |||||||
| @@ -5,6 +5,12 @@ import ( | |||||||
|  |  | ||||||
| 	"github.com/unistack-org/micro/v3/codec" | 	"github.com/unistack-org/micro/v3/codec" | ||||||
| 	"github.com/unistack-org/micro/v3/metadata" | 	"github.com/unistack-org/micro/v3/metadata" | ||||||
|  | 	"github.com/unistack-org/micro/v3/server" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | var ( | ||||||
|  | 	_ server.Request = &rpcRequest{} | ||||||
|  | 	_ server.Message = &rpcMessage{} | ||||||
| ) | ) | ||||||
|  |  | ||||||
| type rpcRequest struct { | type rpcRequest struct { | ||||||
| @@ -16,7 +22,6 @@ type rpcRequest struct { | |||||||
| 	endpoint    string | 	endpoint    string | ||||||
| 	contentType string | 	contentType string | ||||||
| 	service     string | 	service     string | ||||||
| 	target      string |  | ||||||
| 	body        []byte | 	body        []byte | ||||||
| 	stream      bool | 	stream      bool | ||||||
| } | } | ||||||
| @@ -43,7 +48,7 @@ func (r *rpcRequest) Method() string { | |||||||
| } | } | ||||||
|  |  | ||||||
| func (r *rpcRequest) Endpoint() string { | func (r *rpcRequest) Endpoint() string { | ||||||
| 	return r.method | 	return r.endpoint | ||||||
| } | } | ||||||
|  |  | ||||||
| func (r *rpcRequest) Codec() codec.Codec { | func (r *rpcRequest) Codec() codec.Codec { | ||||||
|   | |||||||
| @@ -62,15 +62,14 @@ func prepareEndpoint(method reflect.Method) (*methodType, error) { | |||||||
| 		return nil, fmt.Errorf("method %v of %v has wrong number of ins: %v", mname, mtype, mtype.NumIn()) | 		return nil, fmt.Errorf("method %v of %v has wrong number of ins: %v", mname, mtype, mtype.NumIn()) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if stream { | 	switch stream { | ||||||
|  | 	case true: | ||||||
| 		// check stream type | 		// check stream type | ||||||
| 		streamType := reflect.TypeOf((*server.Stream)(nil)).Elem() | 		streamType := reflect.TypeOf((*server.Stream)(nil)).Elem() | ||||||
| 		if !argType.Implements(streamType) { | 		if !argType.Implements(streamType) { | ||||||
| 			return nil, fmt.Errorf("%v argument does not implement Streamer interface: %v", mname, argType) | 			return nil, fmt.Errorf("%v argument does not implement Streamer interface: %v", mname, argType) | ||||||
| 		} | 		} | ||||||
| 	} else { | 	default: | ||||||
| 		// if not stream check the replyType |  | ||||||
|  |  | ||||||
| 		// First arg need not be a pointer. | 		// First arg need not be a pointer. | ||||||
| 		if !isExportedOrBuiltinType(argType) { | 		if !isExportedOrBuiltinType(argType) { | ||||||
| 			return nil, fmt.Errorf("%v argument type not exported: %v", mname, argType) | 			return nil, fmt.Errorf("%v argument type not exported: %v", mname, argType) | ||||||
|   | |||||||
| @@ -14,10 +14,6 @@ import ( | |||||||
| 	"github.com/unistack-org/micro/v3/server" | 	"github.com/unistack-org/micro/v3/server" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| const ( |  | ||||||
| 	subSig = "func(context.Context, interface{}) error" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| var typeOfError = reflect.TypeOf((*error)(nil)).Elem() | var typeOfError = reflect.TypeOf((*error)(nil)).Elem() | ||||||
|  |  | ||||||
| type handler struct { | type handler struct { | ||||||
| @@ -116,7 +112,7 @@ func (s *httpServer) createSubHandler(sb *httpSubscriber, opts server.Options) b | |||||||
|  |  | ||||||
| 		hdr := metadata.Copy(msg.Header) | 		hdr := metadata.Copy(msg.Header) | ||||||
| 		delete(hdr, "Content-Type") | 		delete(hdr, "Content-Type") | ||||||
| 		ctx := metadata.NewContext(context.Background(), hdr) | 		ctx := metadata.NewIncomingContext(context.Background(), hdr) | ||||||
|  |  | ||||||
| 		results := make(chan error, len(sb.handlers)) | 		results := make(chan error, len(sb.handlers)) | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user