make router fast

This commit is contained in:
JessonChan 2016-03-15 11:49:23 +08:00
parent c8bbfb75f0
commit 8660a54fac
3 changed files with 29 additions and 32 deletions

View File

@ -196,7 +196,7 @@ func listConf(rw http.ResponseWriter, r *http.Request) {
BeforeExec: "Before Exec", BeforeExec: "Before Exec",
AfterExec: "After Exec", AfterExec: "After Exec",
FinishRouter: "Finish Router"} { FinishRouter: "Finish Router"} {
if bf, ok := BeeApp.Handlers.filters[k]; ok { if bf := BeeApp.Handlers.filters[k]; len(bf) > 0 {
filterType = fr filterType = fr
filterTypes = append(filterTypes, filterType) filterTypes = append(filterTypes, filterType)
resultList := new([][]string) resultList := new([][]string)

View File

@ -44,7 +44,7 @@ func NewNamespace(prefix string, params ...LinkNamespace) *Namespace {
return ns return ns
} }
// Cond set condtion function // Cond set condition function
// if cond return true can run this namespace, else can't // if cond return true can run this namespace, else can't
// usage: // usage:
// ns.Cond(func (ctx *context.Context) bool{ // ns.Cond(func (ctx *context.Context) bool{
@ -60,7 +60,7 @@ func (n *Namespace) Cond(cond namespaceCond) *Namespace {
exception("405", ctx) exception("405", ctx)
} }
} }
if v, ok := n.handlers.filters[BeforeRouter]; ok { if v := n.handlers.filters[BeforeRouter]; len(v) > 0 {
mr := new(FilterRouter) mr := new(FilterRouter)
mr.tree = NewTree() mr.tree = NewTree()
mr.pattern = "*" mr.pattern = "*"

View File

@ -114,7 +114,7 @@ type controllerInfo struct {
type ControllerRegister struct { type ControllerRegister struct {
routers map[string]*Tree routers map[string]*Tree
enableFilter bool enableFilter bool
filters map[int][]*FilterRouter filters [5][]*FilterRouter
pool sync.Pool pool sync.Pool
} }
@ -122,7 +122,6 @@ type ControllerRegister struct {
func NewControllerRegister() *ControllerRegister { func NewControllerRegister() *ControllerRegister {
cr := &ControllerRegister{ cr := &ControllerRegister{
routers: make(map[string]*Tree), routers: make(map[string]*Tree),
filters: make(map[int][]*FilterRouter),
} }
cr.pool.New = func() interface{} { cr.pool.New = func() interface{} {
return beecontext.NewContext() return beecontext.NewContext()
@ -408,7 +407,6 @@ func (p *ControllerRegister) AddAutoPrefix(prefix string, c ControllerInterface)
// InsertFilter Add a FilterFunc with pattern rule and action constant. // InsertFilter Add a FilterFunc with pattern rule and action constant.
// The bool params is for setting the returnOnOutput value (false allows multiple filters to execute) // The bool params is for setting the returnOnOutput value (false allows multiple filters to execute)
func (p *ControllerRegister) InsertFilter(pattern string, pos int, filter FilterFunc, params ...bool) error { func (p *ControllerRegister) InsertFilter(pattern string, pos int, filter FilterFunc, params ...bool) error {
mr := new(FilterRouter) mr := new(FilterRouter)
mr.tree = NewTree() mr.tree = NewTree()
mr.pattern = pattern mr.pattern = pattern
@ -426,9 +424,13 @@ func (p *ControllerRegister) InsertFilter(pattern string, pos int, filter Filter
} }
// add Filter into // add Filter into
func (p *ControllerRegister) insertFilterRouter(pos int, mr *FilterRouter) error { func (p *ControllerRegister) insertFilterRouter(pos int, mr *FilterRouter) (err error) {
p.filters[pos] = append(p.filters[pos], mr) if pos < BeforeStatic || pos > FinishRouter {
err = fmt.Errorf("can not find your filter postion")
return
}
p.enableFilter = true p.enableFilter = true
p.filters[pos] = append(p.filters[pos], mr)
return nil return nil
} }
@ -577,20 +579,16 @@ func (p *ControllerRegister) geturl(t *Tree, url, controllName, methodName strin
return false, "" return false, ""
} }
func (p *ControllerRegister) execFilter(context *beecontext.Context, pos int, urlPath string) (started bool) { func (p *ControllerRegister) execFilter(context *beecontext.Context, urlPath string, l []*FilterRouter) (started bool) {
if p.enableFilter { for _, filterR := range l {
if l, ok := p.filters[pos]; ok { if filterR.returnOnOutput && context.ResponseWriter.Started {
for _, filterR := range l { return true
if filterR.returnOnOutput && context.ResponseWriter.Started { }
return true if ok := filterR.ValidRouter(urlPath, context); ok {
} filterR.filterFunc(context)
if ok := filterR.ValidRouter(urlPath, context); ok { }
filterR.filterFunc(context) if filterR.returnOnOutput && context.ResponseWriter.Started {
} return true
if filterR.returnOnOutput && context.ResponseWriter.Started {
return true
}
}
} }
} }
return false return false
@ -617,11 +615,10 @@ func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request)
context.Output.Header("Server", BConfig.ServerName) context.Output.Header("Server", BConfig.ServerName)
} }
var urlPath string var urlPath = r.URL.Path
if !BConfig.RouterCaseSensitive { if !BConfig.RouterCaseSensitive {
urlPath = strings.ToLower(r.URL.Path) urlPath = strings.ToLower(r.URL.Path)
} else {
urlPath = r.URL.Path
} }
// filter wrong http method // filter wrong http method
@ -631,7 +628,7 @@ func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request)
} }
// filter for static file // filter for static file
if p.execFilter(context, BeforeStatic, urlPath) { if fs := p.filters[BeforeStatic]; len(fs) > 0 && p.execFilter(context, urlPath, fs) {
goto Admin goto Admin
} }
@ -663,8 +660,7 @@ func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request)
} }
}() }()
} }
if fs := p.filters[BeforeRouter]; len(fs) > 0 && p.execFilter(context, urlPath, fs) {
if p.execFilter(context, BeforeRouter, urlPath) {
goto Admin goto Admin
} }
@ -693,7 +689,7 @@ func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request)
if findRouter { if findRouter {
//execute middleware filters //execute middleware filters
if p.execFilter(context, BeforeExec, urlPath) { if fs := p.filters[BeforeExec]; len(fs) > 0 && p.execFilter(context, urlPath, fs) {
goto Admin goto Admin
} }
isRunnable := false isRunnable := false
@ -794,12 +790,13 @@ func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request)
} }
//execute middleware filters //execute middleware filters
if p.execFilter(context, AfterExec, urlPath) { if fs := p.filters[AfterExec]; len(fs) > 0 && p.execFilter(context, urlPath, fs) {
goto Admin goto Admin
} }
} }
if fs := p.filters[FinishRouter]; len(fs) > 0 && p.execFilter(context, urlPath, fs) {
p.execFilter(context, FinishRouter, urlPath) goto Admin
}
Admin: Admin:
//admin module record QPS //admin module record QPS