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 }