소스 검색

refactor(transport): 重构传输层中间件和处理器

-将 HTTP 和 gRPC 相关的代码移至 transport 包下
- 重命名相关文件和包以更好地反映其功能和位置
- 新增 recovery 中间件用于处理 panic
- 更新相关测试
dcsunny 4 달 전
부모
커밋
4e9f3b2caf

+ 1 - 1
common/context.go

@@ -4,7 +4,7 @@ import (
 	"context"
 	"time"
 
-	context2 "git.ikuban.com/server/kratos-utils/v2/http/context"
+	context2 "git.ikuban.com/server/kratos-utils/v2/transport/http/context"
 )
 
 func NewContext(parentCtx context.Context) context.Context {

+ 1 - 1
grpc/client.go → transport/grpc/client.go

@@ -6,7 +6,7 @@ import (
 	"time"
 
 	"git.ikuban.com/server/kratos-etcd/registry"
-	"git.ikuban.com/server/kratos-utils/v2/http/middleware/logging"
+	"git.ikuban.com/server/kratos-utils/v2/transport/middleware/logging"
 	"github.com/go-kratos/kratos/v2/log"
 	"github.com/go-kratos/kratos/v2/middleware"
 	"github.com/go-kratos/kratos/v2/transport/grpc"

+ 0 - 0
grpc/define.go → transport/grpc/define.go


+ 0 - 0
http/binding/bind.go → transport/http/binding/bind.go


+ 0 - 0
http/binding/form.go → transport/http/binding/form.go


+ 0 - 0
http/binding/proto.go → transport/http/binding/proto.go


+ 0 - 0
http/context/context.go → transport/http/context/context.go


+ 0 - 0
http/encoding/json/json.go → transport/http/encoding/json/json.go


+ 0 - 0
http/encoding/jsonpb/json.go → transport/http/encoding/jsonpb/json.go


+ 3 - 3
http/handle.go → transport/http/handle.go

@@ -10,15 +10,15 @@ import (
 
 	"git.ikuban.com/server/kratos-utils/v2/codes"
 
-	"git.ikuban.com/server/kratos-utils/v2/http/reply"
+	"git.ikuban.com/server/kratos-utils/v2/transport/http/reply"
 
 	"github.com/go-kratos/kratos/v2/errors"
 
 	"github.com/go-kratos/kratos/v2/encoding"
 	"google.golang.org/protobuf/types/known/emptypb"
 
-	"git.ikuban.com/server/kratos-utils/v2/http/binding"
-	"git.ikuban.com/server/kratos-utils/v2/http/encoding/json"
+	"git.ikuban.com/server/kratos-utils/v2/transport/http/binding"
+	"git.ikuban.com/server/kratos-utils/v2/transport/http/encoding/json"
 	_ "github.com/go-kratos/kratos/v2/encoding/proto"
 )
 

+ 2 - 1
http/handler/route.go → transport/http/handler/route.go

@@ -2,7 +2,8 @@ package handler
 
 import (
 	"fmt"
-	"git.ikuban.com/server/kratos-utils/v2/http/middleware"
+
+	"git.ikuban.com/server/kratos-utils/v2/transport/middleware"
 	ku_annotations "git.ikuban.com/server/kubanapis/kuban/api/annotations"
 	"github.com/go-kratos/kratos/v2/transport/http"
 	openapi_v3 "github.com/google/gnostic/openapiv3"

+ 3 - 2
http/handler/server_stream_handler.go → transport/http/handler/server_stream_handler.go

@@ -4,11 +4,12 @@ import (
 	"context"
 	"encoding/json"
 	"errors"
-	"git.ikuban.com/server/kratos-utils/v2/http/middleware"
+	"strings"
+
+	"git.ikuban.com/server/kratos-utils/v2/transport/middleware"
 	"github.com/go-kratos/kratos/v2/transport/http"
 	"google.golang.org/grpc"
 	"google.golang.org/grpc/metadata"
-	"strings"
 )
 
 func serverStreamHandler(srv any, stream grpc.StreamDesc, option *middleware.Option) http.HandlerFunc {

+ 3 - 2
http/handler/unary_handler.go → transport/http/handler/unary_handler.go

@@ -2,8 +2,9 @@ package handler
 
 import (
 	"context"
-	"git.ikuban.com/server/kratos-utils/v2/http/middleware"
-	"git.ikuban.com/server/kratos-utils/v2/http/reply"
+
+	"git.ikuban.com/server/kratos-utils/v2/transport/http/reply"
+	"git.ikuban.com/server/kratos-utils/v2/transport/middleware"
 	"github.com/go-kratos/kratos/v2/transport/http"
 	"google.golang.org/grpc"
 )

+ 0 - 0
http/reply/reply.go → transport/http/reply/reply.go


+ 0 - 0
mcp/server.go → transport/mcp/server.go


+ 0 - 0
mcp/tools.go → transport/mcp/tools.go


+ 0 - 0
http/middleware/logging/logging.go → transport/middleware/logging/logging.go


+ 0 - 0
http/middleware/option.go → transport/middleware/option.go


+ 64 - 0
transport/middleware/recovery/recovery.go

@@ -0,0 +1,64 @@
+package recovery
+
+import (
+	"context"
+	"encoding/json"
+	"runtime"
+	"time"
+
+	"github.com/go-kratos/kratos/v2/errors"
+	"github.com/go-kratos/kratos/v2/log"
+	"github.com/go-kratos/kratos/v2/middleware"
+)
+
+// Latency is recovery latency context key
+type Latency struct{}
+
+// ErrUnknownRequest is unknown request error.
+var ErrUnknownRequest = errors.InternalServer("UNKNOWN", "unknown request error")
+
+// HandlerFunc is recovery handler func.
+type HandlerFunc func(ctx context.Context, req, err any) error
+
+// Option is recovery option.
+type Option func(*options)
+
+type options struct {
+	handler HandlerFunc
+}
+
+// WithHandler with recovery handler.
+func WithHandler(h HandlerFunc) Option {
+	return func(o *options) {
+		o.handler = h
+	}
+}
+
+// Recovery is a server middleware that recovers from any panics.
+func Recovery(opts ...Option) middleware.Middleware {
+	op := options{
+		handler: func(context.Context, any, any) error {
+			return ErrUnknownRequest
+		},
+	}
+	for _, o := range opts {
+		o(&op)
+	}
+	return func(handler middleware.Handler) middleware.Handler {
+		return func(ctx context.Context, req any) (reply any, err error) {
+			startTime := time.Now()
+			defer func() {
+				if rerr := recover(); rerr != nil {
+					buf := make([]byte, 64<<10) //nolint:mnd
+					n := runtime.Stack(buf, false)
+					buf = buf[:n]
+					reqJson, _ := json.Marshal(req)
+					log.Context(ctx).Errorf("%v: %+v\n%s\n", rerr, string(reqJson), buf)
+					ctx = context.WithValue(ctx, Latency{}, time.Since(startTime).Seconds())
+					err = op.handler(ctx, req, rerr)
+				}
+			}()
+			return handler(ctx, req)
+		}
+	}
+}

+ 42 - 0
transport/middleware/recovery/recovery_test.go

@@ -0,0 +1,42 @@
+package recovery
+
+import (
+	"context"
+	"fmt"
+	"testing"
+
+	"github.com/go-kratos/kratos/v2/errors"
+)
+
+func TestOnce(t *testing.T) {
+	defer func() {
+		if recover() != nil {
+			t.Error("fail")
+		}
+	}()
+
+	next := func(context.Context, any) (any, error) {
+		panic("panic reason")
+	}
+	_, e := Recovery(WithHandler(func(ctx context.Context, _, err any) error {
+		_, ok := ctx.Value(Latency{}).(float64)
+		if !ok {
+			t.Errorf("not latency")
+		}
+		return errors.InternalServer("RECOVERY", fmt.Sprintf("panic triggered: %v", err))
+	}))(next)(context.Background(), "panic")
+	t.Logf("succ and reason is %v", e)
+}
+
+func TestNotPanic(t *testing.T) {
+	next := func(_ context.Context, req any) (any, error) {
+		return req.(string) + "https://go-kratos.dev", nil
+	}
+
+	_, e := Recovery(WithHandler(func(_ context.Context, _ any, err any) error {
+		return errors.InternalServer("RECOVERY", fmt.Sprintf("panic triggered: %v", err))
+	}))(next)(context.Background(), "notPanic")
+	if e != nil {
+		t.Errorf("e isn't nil")
+	}
+}

+ 1 - 1
http/middleware/rpc_value.go → transport/middleware/rpc_value.go

@@ -6,7 +6,7 @@ import (
 	"net/url"
 	"strconv"
 
-	context2 "git.ikuban.com/server/kratos-utils/v2/http/context"
+	context2 "git.ikuban.com/server/kratos-utils/v2/transport/http/context"
 
 	"google.golang.org/grpc/metadata"
 

+ 1 - 1
http/param/auth.go → transport/param/auth.go

@@ -5,7 +5,7 @@ import (
 	"encoding/json"
 )
 
-//GetUserID 为userid
+// GetUserID 为userid
 func GetUserID(c context.Context) int64 {
 	userID := c.Value("user_id")
 	if _, ok := userID.(int64); ok {

+ 0 - 0
http/param/base.go → transport/param/base.go


+ 0 - 0
http/param/page.go → transport/param/page.go


+ 0 - 0
http/param/url.go → transport/param/url.go