github.com/volts-dev/volts@v0.0.0-20240120094013-5e9c65924106/router/handler.go (about)

     1  package router
     2  
     3  // TODO 修改主控制器对应Handler名称让其可以转为统一接口完全规避反射缓慢缺陷
     4  import (
     5  	"fmt"
     6  	"hash/crc32"
     7  	"net/http"
     8  	"path/filepath"
     9  	"reflect"
    10  	"runtime"
    11  	"strings"
    12  	"sync"
    13  
    14  	"github.com/volts-dev/cacher/memory"
    15  	"github.com/volts-dev/utils"
    16  	"github.com/volts-dev/volts/registry"
    17  )
    18  
    19  var deflautHandlerManager = newHandlerManager()
    20  
    21  type HandlerType byte
    22  type TransportType byte
    23  
    24  func (self HandlerType) String() string {
    25  	return [...]string{"LocalHandler", "ProxyHandler", "SubscribeHandler"}[self]
    26  }
    27  
    28  const (
    29  	// type of handler
    30  	LocalHandler HandlerType = iota
    31  	ProxyHandler
    32  	SubscriberHandler
    33  
    34  	HttpHandler TransportType = iota
    35  	RpcHandler
    36  	SubscribeHandler
    37  	ReflectHandler // TODO废弃
    38  )
    39  
    40  type (
    41  	// 让控制器提供基本配置能力
    42  	controllerInit interface {
    43  		Init(*ControllerConfig)
    44  	}
    45  
    46  	handlerManager struct {
    47  		handlerPool sync.Map // map[int]*sync.Pool
    48  		router      *TRouter
    49  	}
    50  
    51  	// 控制器配置 可实现特殊功能
    52  	// 功能:中间件过滤器
    53  	ControllerConfig struct {
    54  		midFilter map[string][]string // TODO sync
    55  	}
    56  
    57  	handle struct {
    58  		IsFunc            bool // 是否以函数调用
    59  		MiddlewareCreator func(IRouter) IMiddleware
    60  		Middleware        IMiddleware               // 以供调用初始化和其他使用接口调用以达到直接调用的效率
    61  		HttpFunc          func(*THttpContext)       // 实际调用的HTTP处理器
    62  		RpcFunc           func(*TRpcContext)        // 实际调用的RPC处理器
    63  		SubFunc           func(*TSubscriberContext) // 订阅处理器
    64  	}
    65  
    66  	// 路由节点绑定的控制器 func(Handler)
    67  	handler struct {
    68  		Manager  *handlerManager
    69  		Config   *ControllerConfig
    70  		Services []*registry.Service // 该路由服务线路 提供网关等特殊服务用// Versions of this service
    71  
    72  		Id            int           // 根据Name生成的UID用于缓存
    73  		Name          string        // handler名称
    74  		FuncName      string        // handler方法名称
    75  		Type          HandlerType   // Route 类型 决定合并的形式
    76  		TransportType TransportType //
    77  		pos           int           // current handle position
    78  
    79  		// 多处理器包括中间件
    80  		funcs []*handle
    81  
    82  		// 控制器提供[结构控制器]数据和中间件载体
    83  		ctrlName  string        // 区别不同[结构型控制器]
    84  		ctrlType  reflect.Type  // 供生成新的控制器
    85  		ctrlValue reflect.Value // 每个handler的控制器必须是唯一的
    86  		ctrlModel interface{}   // 提供Ctx特殊调用
    87  	}
    88  )
    89  
    90  func WrapHttp(fn func(IContext)) func(*THttpContext) {
    91  	return func(ctx *THttpContext) {
    92  		fn(ctx)
    93  	}
    94  }
    95  
    96  func WrapRpc(fn func(IContext)) func(*TRpcContext) {
    97  	return func(ctx *TRpcContext) {
    98  		fn(ctx)
    99  	}
   100  }
   101  
   102  // WrapFn is a helper function for wrapping http.HandlerFunc and returns a HttpContext.
   103  func WrapFn(fn http.HandlerFunc) func(*THttpContext) {
   104  	return func(ctx *THttpContext) {
   105  		fn(ctx.response.ResponseWriter, ctx.request.Request)
   106  	}
   107  }
   108  
   109  // WrapH is a helper function for wrapping http.Handler and returns a  HttpContext.
   110  func WrapHd(h http.Handler) func(*THttpContext) {
   111  	return func(ctx *THttpContext) {
   112  		h.ServeHTTP(ctx.response.ResponseWriter, ctx.request.Request)
   113  	}
   114  }
   115  
   116  func GetFuncName(i interface{}, seps ...rune) string {
   117  	// 获取函数名称
   118  	var fn string
   119  	if v, ok := i.(reflect.Value); ok {
   120  		fn = v.Type().String()
   121  		fn = runtime.FuncForPC(v.Pointer()).Name()
   122  	} else {
   123  		fn = runtime.FuncForPC(reflect.ValueOf(i).Pointer()).Name()
   124  	}
   125  
   126  	// 用 seps 进行分割
   127  	fields := strings.FieldsFunc(fn, func(sep rune) bool {
   128  		for _, s := range seps {
   129  			if sep == s {
   130  				return true
   131  			}
   132  		}
   133  		return false
   134  	})
   135  
   136  	if size := len(fields); size > 0 {
   137  		return fields[size-1]
   138  	}
   139  	return ""
   140  }
   141  
   142  func newHandlerManager() *handlerManager {
   143  	return &handlerManager{
   144  		// handlerPool: make(map[int]*sync.Pool),
   145  	}
   146  }
   147  
   148  /*
   149  @controller:本地服务会自行本地控制程序 其他代理远程服务为nil
   150  */
   151  // 生成handler原型
   152  // NOTE:不可用于实时环境
   153  func generateHandler(hanadlerType HandlerType, tt TransportType, handlers []any, middlewares []any, url *TUrl, services []*registry.Service) *handler {
   154  	httpFn := func(h *handler, middlewares []any) {
   155  		for _, mid := range middlewares {
   156  			switch v := mid.(type) {
   157  			case func(IContext):
   158  				h.funcs = append(h.funcs, &handle{IsFunc: true, HttpFunc: WrapHttp(v)})
   159  			case func(*THttpContext):
   160  				h.funcs = append(h.funcs, &handle{IsFunc: true, HttpFunc: v})
   161  			case func(IRouter) IMiddleware: // 创建新的中间件状态实例并调用传递中间件
   162  				//middleware := v()
   163  				h.funcs = append(h.funcs, &handle{IsFunc: true, MiddlewareCreator: v /*, Middleware: middleware, HttpFunc: WrapHttp(middleware.Handler)*/})
   164  			default:
   165  				log.Errf("unknow middleware %v", v)
   166  			}
   167  		}
   168  	}
   169  	rpcFn := func(h *handler, middlewares []any) {
   170  		for _, mid := range middlewares {
   171  			switch v := mid.(type) {
   172  			case func(IContext):
   173  				h.funcs = append(h.funcs, &handle{IsFunc: true, RpcFunc: WrapRpc(v)})
   174  			case func(*TRpcContext):
   175  				h.funcs = append(h.funcs, &handle{IsFunc: true, RpcFunc: v})
   176  			case func(IRouter) IMiddleware:
   177  				//middleware := v()
   178  				h.funcs = append(h.funcs, &handle{IsFunc: true, MiddlewareCreator: v /* Middleware: middleware, RpcFunc: WrapRpc(middleware.Handler)*/})
   179  			default:
   180  				log.Errf("unknow middleware %v", v)
   181  			}
   182  		}
   183  	}
   184  	h := &handler{
   185  		Manager:  deflautHandlerManager,
   186  		Config:   &ControllerConfig{},
   187  		Type:     hanadlerType,
   188  		Services: services,
   189  		pos:      -1,
   190  	}
   191  	// 生成唯一标识用于缓存
   192  	h.Id = int(crc32.ChecksumIEEE([]byte(url.Path)))
   193  	h.Name = fmt.Sprintf("%s-%d", GetFuncName(handlers[0], filepath.Separator), h.Id)
   194  
   195  	switch val := handlers[0].(type) {
   196  	case func(*THttpContext):
   197  		h.TransportType = HttpHandler
   198  		httpFn(h, middlewares)
   199  		h.funcs = append(h.funcs, &handle{IsFunc: true, HttpFunc: val})
   200  	case func(*TRpcContext):
   201  		h.TransportType = RpcHandler
   202  		rpcFn(h, middlewares)
   203  		h.funcs = append(h.funcs, &handle{IsFunc: true, RpcFunc: val})
   204  	case reflect.Value:
   205  		// 以下处理带控制器的处理器
   206  		// Example: ctroller.method
   207  		handlerType := val.Type()
   208  		numIn := handlerType.NumIn()
   209  		if numIn == 1 && (handlerType.In(0) != ContextType && handlerType.In(0) != HttpContextType && handlerType.In(0) != RpcContextType) {
   210  			log.Panicf("the handler %s must including Context!", h.Name)
   211  		}
   212  		if handlerType.In(0).Kind() != reflect.Struct || (handlerType.In(1) != ContextType && handlerType.In(1) != HttpContextType && handlerType.In(1) != RpcContextType) {
   213  			log.Panicf("the handler %s receiver must not be a pointer and with HTTP/RPC context!", h.Name)
   214  		}
   215  		// 这是控制器上的某个方法 提取控制器和中间件
   216  		h.ctrlType = handlerType.In(0)
   217  		if h.ctrlType.Kind() == reflect.Pointer {
   218  			h.ctrlType = h.ctrlType.Elem()
   219  		}
   220  
   221  		// 变更控制器名称
   222  		if url.Controller != "" {
   223  			h.ctrlName = url.Controller
   224  		} else {
   225  			h.ctrlName = h.ctrlType.Name()
   226  		}
   227  
   228  		// 检测获取绑定的handler
   229  		h.FuncName = GetFuncName(handlers[0], '.')
   230  		if !utils.IsStartUpper(h.FuncName) {
   231  			log.Dbgf("the handler %s.%s must start with upper letter!", h.ctrlName, h.FuncName)
   232  		}
   233  
   234  		hd, ok := h.ctrlType.MethodByName(h.FuncName)
   235  		if !ok {
   236  			log.Dbgf("handler %s not exist in controller %s!", h.FuncName, h.ctrlType.Name())
   237  		}
   238  
   239  		h.TransportType = tt
   240  		switch tt {
   241  		case HttpHandler:
   242  			httpFn(h, middlewares)
   243  		case RpcHandler:
   244  			rpcFn(h, middlewares)
   245  		default:
   246  			log.Panicf("the middleware.handler %v is not supportable!", hd)
   247  		}
   248  		/*
   249  			var midVal reflect.Value
   250  			//var midhd reflect.Value
   251  			for i := 0; i < h.ctrlValue.NumField(); i++ {
   252  				midVal = h.ctrlValue.Field(i) // get the middleware value
   253  
   254  				if midVal.Kind() == reflect.Struct && h.ctrlValue.Type().Field(0).Name == midVal.Type().Name() {
   255  					// 非指针且是继承的检测
   256  					// 由于 继承的变量名=结构名称
   257  					// Example:Event
   258  					//midhd = ctrl.MethodByName("Handler")
   259  					log.Dbg(ctrl.Interface(), midVal.Type().String(), ctrl.Interface().(IMiddleware))
   260  					if mw, ok := ctrl.Interface().(IMiddleware); ok {
   261  						if h.TransportType != HttpHandler {
   262  							h.RpcFuncs = append(h.RpcFuncs, &handle{IsFunc: false, Middleware: mw})
   263  						} else {
   264  							h.HttpFuncs = append(h.HttpFuncs, &handle{IsFunc: false, Middleware: mw})
   265  						}
   266  					}
   267  				} else {
   268  					//log.Dbg(midVal.Interface(), midVal.Type().String(), midVal.Interface().(IMiddleware))
   269  					if mw, ok := midVal.Interface().(IMiddleware); ok {
   270  						if h.TransportType != HttpHandler {
   271  							h.RpcFuncs = append(h.RpcFuncs, &handle{IsFunc: false, Middleware: mw})
   272  						} else {
   273  							h.HttpFuncs = append(h.HttpFuncs, &handle{IsFunc: false, Middleware: mw})
   274  						}
   275  					}
   276  					//midhd = midVal.MethodByName("Handler")
   277  				}
   278  				/*
   279  					switch midhd.Type().In(0) {
   280  					case HttpContextType:
   281  						if h.TransportType != HttpHandler {
   282  							log.Panicf("handler and its middleware must one of Http or RPC context!")
   283  						}
   284  						h.HttpFuncs = append(h.HttpFuncs, &handle{IsFunc: false, HttpFunc: midhd.Interface().(func(*THttpContext))})
   285  					case RpcContextType:
   286  						if h.TransportType != RpcHandler {
   287  							log.Panicf("handler and its middleware must one of Http or RPC context!")
   288  						}
   289  						h.RpcFuncs = append(h.RpcFuncs, &handle{IsFunc: false, RpcFunc: midhd.Interface().(func(*TRpcContext))})
   290  					case ContextType:
   291  						if h.TransportType == HttpHandler {
   292  							h.HttpFuncs = append(h.HttpFuncs, func(ctx *THttpContext) {
   293  								fn := midhd.Interface().(func(IContext))
   294  								fn(ctx)
   295  							})
   296  							break
   297  						} else if h.TransportType == RpcHandler {
   298  							h.RpcFuncs = append(h.RpcFuncs, func(ctx *TRpcContext) {
   299  								fn := midhd.Interface().(func(IContext))
   300  								fn(ctx)
   301  							})
   302  							break
   303  						}
   304  						fallthrough
   305  					default:
   306  						log.Panicf("the middleware.handler %v is not supportable!", midhd.String())
   307  					}
   308  		*/
   309  	/*	}
   310  
   311  
   312  	 */
   313  	default:
   314  		log.Panicf("can not gen handler by this type")
   315  	}
   316  	return h
   317  }
   318  
   319  // add which middleware name blocked handler name
   320  func (self *ControllerConfig) AddFilter(middleware string, handlers ...string) {
   321  	if self.midFilter == nil {
   322  		self.midFilter = make(map[string][]string)
   323  	}
   324  	lst := self.midFilter[middleware]
   325  	for _, name := range handlers {
   326  		if utils.InStrings(name, lst...) == -1 {
   327  			lst = append(lst, name)
   328  		}
   329  	}
   330  	self.midFilter[middleware] = lst
   331  }
   332  
   333  func (self *handlerManager) Get(id int) *handler {
   334  	if v, ok := self.handlerPool.Load(id); ok {
   335  		if h := v.(memory.StackCache).Pop(); h != nil {
   336  			return h.(*handler)
   337  		}
   338  	}
   339  
   340  	return nil
   341  }
   342  
   343  func (self *handlerManager) Put(id int, h *handler) {
   344  	var c memory.StackCache
   345  	if v, ok := self.handlerPool.Load(id); ok {
   346  		c = v.(memory.StackCache)
   347  	} else {
   348  		c = memory.NewStack(
   349  			memory.WithInterval(60),
   350  			memory.WithExpire(3600),
   351  		) // cacher
   352  		self.handlerPool.Store(id, c)
   353  	}
   354  
   355  	c.Push(h)
   356  }
   357  
   358  // 处理器名称
   359  func (self *handler) String() string {
   360  	return self.FuncName
   361  }
   362  
   363  // 控制器名称如果无控制器为空
   364  func (self *handler) ControllerName() string {
   365  	return self.ctrlName
   366  }
   367  
   368  // 控制器实例
   369  func (self *handler) Controller() any {
   370  	return self.ctrlModel
   371  }
   372  
   373  // 初始化生成新的处理器
   374  // 任务:创建/缓存/初始化
   375  // 调用Recycle回收
   376  func (self *handler) init(router *TRouter) *handler {
   377  	/*p, has := self.Manager.handlerPool[self.Id]
   378  	if !has {
   379  		p = &sync.Pool{}
   380  		self.Manager.handlerPool[self.Id] = p // FIXME map 有风险崩溃
   381  	}
   382  
   383  	itf := p.Get()
   384  	if itf != nil {
   385  		return itf.((*handler))
   386  	}*/
   387  	h := self.Manager.Get(self.Id)
   388  	if h != nil {
   389  		return h
   390  	}
   391  
   392  	h = &handler{}
   393  	*h = *self //复制handler原型
   394  	if h.ctrlName != "" {
   395  		// 新建控制器
   396  		h.ctrlValue = reflect.New(h.ctrlType)
   397  		ctrl := h.ctrlValue.Elem()
   398  
   399  		// 初始化控制器配置
   400  		// 断言必须非Elem()
   401  		if c, ok := h.ctrlValue.Interface().(controllerInit); ok {
   402  			c.Init(h.Config)
   403  		}
   404  
   405  		var (
   406  			midVal  reflect.Value
   407  			midTyp  reflect.Type
   408  			midName string // name of middleware
   409  		)
   410  
   411  		// 赋值中间件
   412  		// 修改成员
   413  		for i := 0; i < ctrl.NumField(); i++ {
   414  			midVal = ctrl.Field(i) // get the middleware value
   415  			midTyp = midVal.Type() // get the middleware type
   416  
   417  			if midTyp.Kind() == reflect.Ptr {
   418  				midTyp = midTyp.Elem()
   419  			}
   420  
   421  			// get the name of middleware from the Type or Name()
   422  			midName = midTyp.String()
   423  			var midItf any
   424  			if midVal.Kind() == reflect.Ptr {
   425  				// 使用命名中间件
   426  				midItf = midVal.Interface()
   427  			} else if midVal.Kind() == reflect.Struct && ctrl.Type().Field(0).Name == midTyp.Name() {
   428  				// 非指针且是继承的检测
   429  				// 由于 继承的变量名=结构名称
   430  				// Example:Event
   431  				midItf = ctrl.Interface()
   432  			}
   433  
   434  			// 过滤非中间件
   435  			if _, ok := midItf.(IMiddleware); !ok {
   436  				continue
   437  			}
   438  
   439  			// 自定义名称
   440  			if m, ok := midItf.(IMiddlewareName); ok { // ctrl must be a value pointer to provide pointer methods
   441  				midName = m.Name()
   442  			}
   443  
   444  			ml := router.middleware.Get(midName)
   445  			if ml == nil {
   446  				log.Panicf("Controller %s need middleware %s to be registered!", h.ctrlName, midName)
   447  			}
   448  
   449  			midNewVal := reflect.ValueOf(ml(router))
   450  			/***	!过滤指针中间件!
   451  				type Controller struct {
   452  					Session *TSession
   453  				}
   454  			***/
   455  			if midVal.Kind() == reflect.Ptr {
   456  				midVal.Set(midNewVal) // WARM: Field must exportable
   457  			} else if midVal.Kind() == reflect.Struct {
   458  				midVal.Set(midNewVal.Elem())
   459  			}
   460  
   461  			// 检测中间件黑名单
   462  			if lst, ok := h.Config.midFilter[midName]; ok {
   463  				for _, name := range lst {
   464  					if strings.ToLower(name) == strings.ToLower(h.FuncName) {
   465  						goto next
   466  					}
   467  				}
   468  			}
   469  
   470  			// 添加中间件
   471  			if midVal.Kind() == reflect.Struct && ctrl.Type().Field(0).Name == midVal.Type().Name() {
   472  				// 非指针且是继承的检测
   473  				// 由于 继承的变量名=结构名称
   474  				// Example:Event
   475  				//log.Dbg(ctrl.Interface(), midVal.Type().String(), ctrl.Interface().(IMiddleware))
   476  				if mw, ok := ctrl.Interface().(IMiddleware); ok {
   477  					h.funcs = append(h.funcs, &handle{IsFunc: false, Middleware: mw})
   478  				}
   479  			} else {
   480  				//log.Dbg(midVal.Interface(), midVal.Type().String(), midVal.Interface().(IMiddleware))
   481  				if mw, ok := midVal.Interface().(IMiddleware); ok {
   482  					h.funcs = append(h.funcs, &handle{IsFunc: false, Middleware: mw})
   483  				}
   484  			}
   485  		next:
   486  		}
   487  
   488  		// 写入handler
   489  		// MethodByName特性取到的值receiver默认为v
   490  		hd := ctrl.MethodByName(h.FuncName)
   491  		switch hd.Type().In(0) {
   492  		case ContextType:
   493  			if fn, ok := hd.Interface().(func(IContext)); ok {
   494  				if h.TransportType != HttpHandler {
   495  					h.funcs = append(h.funcs, &handle{IsFunc: true, RpcFunc: WrapRpc(fn)})
   496  				} else {
   497  					h.funcs = append(h.funcs, &handle{IsFunc: true, HttpFunc: WrapHttp(fn)})
   498  				}
   499  			}
   500  		case RpcContextType:
   501  			h.funcs = append(h.funcs, &handle{IsFunc: true, RpcFunc: hd.Interface().(func(*TRpcContext))})
   502  		case HttpContextType:
   503  			h.funcs = append(h.funcs, &handle{IsFunc: true, HttpFunc: hd.Interface().(func(*THttpContext))})
   504  		default:
   505  			log.Errf("the handler %v is not supportable!", hd)
   506  		}
   507  
   508  		// 所有的指针准备就绪后生成Interface
   509  		// NOTE:必须初始化结构指针才能生成完整的Model,之后修改CtrlValue将不会有效果
   510  		h.ctrlModel = h.ctrlValue.Interface()
   511  	}
   512  
   513  	/* 初始化中间件 */
   514  	for _, handle := range h.funcs {
   515  		if handle.Middleware == nil && handle.MiddlewareCreator != nil {
   516  			middleware := handle.MiddlewareCreator(router)
   517  			handle.Middleware = middleware
   518  			handle.HttpFunc = WrapHttp(middleware.Handler)
   519  			handle.RpcFunc = WrapRpc(middleware.Handler)
   520  		}
   521  	}
   522  
   523  	h.reset()
   524  	return h
   525  }
   526  
   527  func (self *handler) Invoke(ctx IContext) *handler {
   528  	ctx.setHandler(self)
   529  
   530  	self.pos++
   531  	switch self.TransportType {
   532  	case HttpHandler:
   533  		c := ctx.(*THttpContext)
   534  		for self.pos < len(self.funcs) {
   535  			if c.IsDone() {
   536  				break
   537  			}
   538  			hd := self.funcs[self.pos]
   539  			if hd.IsFunc {
   540  				hd.HttpFunc(c)
   541  			} else {
   542  				hd.Middleware.Handler(c)
   543  			}
   544  			self.pos++
   545  		}
   546  	case RpcHandler:
   547  		c := ctx.(*TRpcContext)
   548  		for self.pos < len(self.funcs) {
   549  			if c.IsDone() {
   550  				break
   551  			}
   552  			hd := self.funcs[self.pos]
   553  			if hd.IsFunc {
   554  				hd.RpcFunc(c)
   555  			} else {
   556  				hd.Middleware.Handler(c)
   557  			}
   558  			self.pos++
   559  		}
   560  	case ReflectHandler:
   561  		log.Panicf("ReflectHandler %v")
   562  		/*
   563  			for self.pos < len(self.funcs) {
   564  				if ctx.IsDone() {
   565  					break
   566  				}
   567  				v := self.funcs[self.pos]
   568  				rcv := self.FuncsReceiver[self.pos]
   569  				if rcv.IsValid() {
   570  					v.Call([]reflect.Value{rcv, ctx.ValueModel()})
   571  				} else {
   572  					v.Call([]reflect.Value{ctx.ValueModel()})
   573  				}
   574  
   575  				self.pos++
   576  			}
   577  		*/
   578  
   579  	}
   580  
   581  	return self
   582  }
   583  
   584  // 初始化
   585  // NOTE:仅限于回收使用
   586  func (self *handler) reset() *handler {
   587  	// 执行中间件初始化
   588  	for _, handle := range self.funcs {
   589  		if handle.Middleware != nil {
   590  			if m, ok := handle.Middleware.(IMiddlewareRest); ok {
   591  				m.Rest()
   592  			}
   593  		}
   594  	}
   595  
   596  	self.pos = -1
   597  	return self
   598  }
   599  
   600  func (self *handler) recycle() *handler {
   601  	self.reset()
   602  	//p.Put(self)
   603  	self.Manager.Put(self.Id, self)
   604  	return self
   605  }