代码拉取完成,页面将自动刷新
package route
import (
"errors"
"fmt"
"reflect"
"runtime"
"strings"
"sync"
"gitee.com/pangxianfei/frame/app"
"gitee.com/pangxianfei/frame/helpers/log"
"gitee.com/pangxianfei/frame/helpers/toto"
"gitee.com/pangxianfei/frame/http/middleware"
"gitee.com/pangxianfei/frame/policy"
"gitee.com/pangxianfei/frame/request"
"gitee.com/pangxianfei/frame/request/websocket"
)
var RouteNameMap *routeNameMap
type routeNameMap struct {
lock sync.RWMutex
data map[string]string
}
func newRouteNameMap() *routeNameMap {
return &routeNameMap{
data: make(map[string]string),
}
}
func (rnm *routeNameMap) set(routeName, routeUrl string) {
rnm.lock.Lock()
defer rnm.lock.Unlock()
rnm.data[routeName] = routeUrl
}
func (rnm *routeNameMap) Get(routeName string, param toto.S) (url string, err error) {
rnm.lock.RLock()
defer rnm.lock.RUnlock()
routeUrl, ok := rnm.data[routeName]
if !strings.Contains(routeUrl, "/:") {
// simple url
return routeUrl, nil
}
// param url
if !ok {
return "", errors.New("Cannot find route by Name " + routeName)
}
for k, v := range param {
routeUrl = strings.Replace(routeUrl, "/:"+k, v, 1)
}
return routeUrl, nil
}
type route struct {
name string
bindFunc func(handlers ...request.HandlerFunc)
handlers []request.HandlerFunc
relativePath string
httpMethod string
basicPath string
prefixHandlersNum int
wsHandler websocket.Handler
}
const maxRouteMapLength = 1000
type engineRoute struct {
lock sync.RWMutex
data map[request.EngineHash]chan *route
}
func newEngineRoute() *engineRoute {
return &engineRoute{
data: make(map[request.EngineHash]chan *route),
}
}
func (erm *engineRoute) initEngine(eh request.EngineHash) {
if erm.data[eh] == nil {
erm.data[eh] = make(chan *route, maxRouteMapLength)
}
}
func (erm *engineRoute) Get(eh request.EngineHash) chan *route {
erm.lock.RLock()
defer erm.lock.RUnlock()
return erm.data[eh]
}
func (erm *engineRoute) Set(eh request.EngineHash, r *route) {
//@todo doesn't process the situation that for multi serve
erm.lock.Lock()
defer erm.lock.Unlock()
erm.initEngine(eh)
erm.data[eh] <- r
}
func (erm *engineRoute) Close(eh request.EngineHash) {
close(erm.data[eh])
}
var engineRouteMap *engineRoute
func init() {
engineRouteMap = newEngineRoute()
RouteNameMap = newRouteNameMap()
}
func newRoute(httpMethod string, g *group, relativePath string, bindFunc func(ginHandlers ...request.HandlerFunc), handlers ...request.HandlerFunc) *route {
r := route{httpMethod: httpMethod, prefixHandlersNum: len(g.RouterGroup.Handlers), basicPath: g.RouterGroup.BasePath(), relativePath: relativePath, bindFunc: bindFunc, handlers: handlers}
engineRouteMap.Set(g.engineHash, &r)
return &r
}
func newWsRoute(httpMethod string, g *group, relativePath string, bindWsFunc func(wsHandler websocket.Handler, ginHandlers ...request.HandlerFunc), wsHandler websocket.Handler, handlers ...request.HandlerFunc) *route {
r := route{wsHandler: wsHandler, httpMethod: httpMethod, prefixHandlersNum: len(g.RouterGroup.Handlers), basicPath: g.RouterGroup.BasePath(), relativePath: relativePath, bindFunc: func(handlers ...request.HandlerFunc) {
// normalHandler -> wshandler
httpHs := append(handlers, func(context request.Context) {
//@todo websocket handler placeholder
})
bindWsFunc(wsHandler, httpHs...)
}, handlers: handlers}
engineRouteMap.Set(g.engineHash, &r)
return &r
}
func (r *route) Name(routeName string) policy.RoutePolicier {
r.name = routeName
return r
}
func (r *route) Can(policies policy.Policier, action policy.Action) {
r.handlers = append([]request.HandlerFunc{middleware.Policy(policies, action)}, r.handlers...)
}
func (r *route) handlerNum() int {
return r.prefixHandlersNum + len(r.handlers)
}
func (r *route) absolutePath() string {
return fmt.Sprintf("%s%s", r.basicPath, r.relativePath)
}
func (r *route) lastHandlerName() string {
if r.httpMethod == httpMethodWebsocket {
h := reflect.ValueOf(r.wsHandler).Elem().Type()
return h.PkgPath() + "." + h.Name()
}
if len(r.handlers) > 0 {
return runtime.FuncForPC(reflect.ValueOf(r.handlers[len(r.handlers)-1]).Pointer()).Name()
}
return "nil"
}
func Bind(engine *request.Engine) {
hash := engine.Hash()
defer engineRouteMap.Close(hash)
for r := range engineRouteMap.Get(hash) {
r.bindFunc(r.handlers...)
// for Route() function to easy retrieve url by name
RouteNameMap.set(r.name, r.absolutePath())
if app.GetMode() != app.ModeProduction {
log.Info(fmt.Sprintf("%-6s %-30s --> %s (%d handlers)\n", r.httpMethod, r.absolutePath(), r.lastHandlerName(), r.handlerNum()))
}
if len(engineRouteMap.Get(hash)) <= 0 {
break
}
}
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。