mirror of https://github.com/gofiber/fiber.git
v3: fix benchmark results related to handler, next (#2130)
parent
7fb50f11f6
commit
23b817083b
14
ctx.go
14
ctx.go
|
@ -728,7 +728,11 @@ func (c *DefaultCtx) Next() (err error) {
|
||||||
err = c.route.Handlers[c.indexHandler](c)
|
err = c.route.Handlers[c.indexHandler](c)
|
||||||
} else {
|
} else {
|
||||||
// Continue handler stack
|
// Continue handler stack
|
||||||
_, err = c.app.next(c, c.app.newCtxFunc != nil)
|
if c.app.newCtxFunc != nil {
|
||||||
|
_, err = c.app.nextCustom(c)
|
||||||
|
} else {
|
||||||
|
_, err = c.app.next(c)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -736,8 +740,14 @@ func (c *DefaultCtx) Next() (err error) {
|
||||||
// RestartRouting instead of going to the next handler. This may be usefull after
|
// RestartRouting instead of going to the next handler. This may be usefull after
|
||||||
// changing the request path. Note that handlers might be executed again.
|
// changing the request path. Note that handlers might be executed again.
|
||||||
func (c *DefaultCtx) RestartRouting() error {
|
func (c *DefaultCtx) RestartRouting() error {
|
||||||
|
var err error
|
||||||
|
|
||||||
c.indexRoute = -1
|
c.indexRoute = -1
|
||||||
_, err := c.app.next(c, c.app.newCtxFunc != nil)
|
if c.app.newCtxFunc != nil {
|
||||||
|
_, err = c.app.nextCustom(c)
|
||||||
|
} else {
|
||||||
|
_, err = c.app.next(c)
|
||||||
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
63
router.go
63
router.go
|
@ -96,7 +96,7 @@ func (r *Route) match(detectionPath, path string, params *[maxParams]string) (ma
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *App) next(c CustomCtx, customCtx bool) (match bool, err error) {
|
func (app *App) nextCustom(c CustomCtx) (match bool, err error) {
|
||||||
// Get stack length
|
// Get stack length
|
||||||
tree, ok := app.treeStack[c.getMethodINT()][c.getTreePath()]
|
tree, ok := app.treeStack[c.getMethodINT()][c.getTreePath()]
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -136,22 +136,64 @@ func (app *App) next(c CustomCtx, customCtx bool) (match bool, err error) {
|
||||||
// If c.Next() does not match, return 404
|
// If c.Next() does not match, return 404
|
||||||
err = NewError(StatusNotFound, "Cannot "+c.Method()+" "+c.getPathOriginal())
|
err = NewError(StatusNotFound, "Cannot "+c.Method()+" "+c.getPathOriginal())
|
||||||
|
|
||||||
var isMethodExist bool
|
// If no match, scan stack again if other methods match the request
|
||||||
if customCtx {
|
// Moved from app.handler because middleware may break the route chain
|
||||||
isMethodExist = methodExistCustom(c)
|
if !c.getMatched() && methodExistCustom(c) {
|
||||||
} else {
|
err = ErrMethodNotAllowed
|
||||||
isMethodExist = methodExist(c.(*DefaultCtx))
|
|
||||||
}
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (app *App) next(c *DefaultCtx) (match bool, err error) {
|
||||||
|
// Get stack length
|
||||||
|
tree, ok := app.treeStack[c.methodINT][c.treePath]
|
||||||
|
if !ok {
|
||||||
|
tree = app.treeStack[c.methodINT][""]
|
||||||
|
}
|
||||||
|
lenr := len(tree) - 1
|
||||||
|
|
||||||
|
// Loop over the route stack starting from previous index
|
||||||
|
for c.indexRoute < lenr {
|
||||||
|
// Increment route index
|
||||||
|
c.indexRoute++
|
||||||
|
|
||||||
|
// Get *Route
|
||||||
|
route := tree[c.indexRoute]
|
||||||
|
|
||||||
|
// Check if it matches the request path
|
||||||
|
match = route.match(c.detectionPath, c.path, &c.values)
|
||||||
|
|
||||||
|
// No match, next route
|
||||||
|
if !match {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// Pass route reference and param values
|
||||||
|
c.route = route
|
||||||
|
|
||||||
|
// Non use handler matched
|
||||||
|
if !c.matched && !route.use {
|
||||||
|
c.matched = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute first handler of route
|
||||||
|
c.indexHandler = 0
|
||||||
|
err = route.Handlers[0](c)
|
||||||
|
return match, err // Stop scanning the stack
|
||||||
|
}
|
||||||
|
|
||||||
|
// If c.Next() does not match, return 404
|
||||||
|
err = NewError(StatusNotFound, "Cannot "+c.method+" "+c.pathOriginal)
|
||||||
|
|
||||||
// If no match, scan stack again if other methods match the request
|
// If no match, scan stack again if other methods match the request
|
||||||
// Moved from app.handler because middleware may break the route chain
|
// Moved from app.handler because middleware may break the route chain
|
||||||
if !c.getMatched() && isMethodExist {
|
if !c.matched && methodExist(c) {
|
||||||
err = ErrMethodNotAllowed
|
err = ErrMethodNotAllowed
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *App) handler(rctx *fasthttp.RequestCtx) {
|
func (app *App) handler(rctx *fasthttp.RequestCtx) {
|
||||||
|
// Handler for default ctxs
|
||||||
var c CustomCtx
|
var c CustomCtx
|
||||||
if app.newCtxFunc != nil {
|
if app.newCtxFunc != nil {
|
||||||
c = app.AcquireCtx().(CustomCtx)
|
c = app.AcquireCtx().(CustomCtx)
|
||||||
|
@ -173,7 +215,12 @@ func (app *App) handler(rctx *fasthttp.RequestCtx) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find match in stack
|
// Find match in stack
|
||||||
_, err := app.next(c, app.newCtxFunc != nil)
|
var err error
|
||||||
|
if app.newCtxFunc != nil {
|
||||||
|
_, err = app.nextCustom(c)
|
||||||
|
} else {
|
||||||
|
_, err = app.next(c.(*DefaultCtx))
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if catch := c.App().ErrorHandler(c, err); catch != nil {
|
if catch := c.App().ErrorHandler(c, err); catch != nil {
|
||||||
_ = c.SendStatus(StatusInternalServerError)
|
_ = c.SendStatus(StatusInternalServerError)
|
||||||
|
|
|
@ -596,7 +596,7 @@ func Benchmark_Router_Next(b *testing.B) {
|
||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
for n := 0; n < b.N; n++ {
|
for n := 0; n < b.N; n++ {
|
||||||
c.indexRoute = -1
|
c.indexRoute = -1
|
||||||
res, err = app.next(c, false)
|
res, err = app.next(c)
|
||||||
}
|
}
|
||||||
require.NoError(b, err)
|
require.NoError(b, err)
|
||||||
require.True(b, res)
|
require.True(b, res)
|
||||||
|
@ -772,10 +772,10 @@ func Benchmark_Router_Github_API(b *testing.B) {
|
||||||
for n := 0; n < b.N; n++ {
|
for n := 0; n < b.N; n++ {
|
||||||
c.URI().SetPath(routesFixture.TestRoutes[i].Path)
|
c.URI().SetPath(routesFixture.TestRoutes[i].Path)
|
||||||
|
|
||||||
ctx := app.AcquireCtx().(CustomCtx)
|
ctx := app.AcquireCtx().(*DefaultCtx)
|
||||||
ctx.Reset(c)
|
ctx.Reset(c)
|
||||||
|
|
||||||
match, err = app.next(ctx, false)
|
match, err = app.next(ctx)
|
||||||
app.ReleaseCtx(ctx)
|
app.ReleaseCtx(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue